使用Safari和Apache 2.2.3获取Javascript /图像资源时,为什么有些页面请求会挂起?

时间:2009-07-07 10:36:08

标签: ruby-on-rails apache safari

我们的Ruby on Rails应用程序的一些用户抱怨页面请求偶尔会在Safari下无限期挂起(一对夫妇在Firefox下注意到它,但它绝大多数是Safari用户)。经过一些调查后,我们的Rails应用程序似乎正确地提供了这些请求,并且在获取HTML中引用的图像资源(托管在同一服务器上)时会发生挂起。

我们已将Apache配置为直接提供图像资源,并绕过Rails应用程序以提高性能。我们还在text / javascript / css资产上启用了gzip压缩。以下是我们的Apache虚拟主机配置中的相关设置 - 也许我们已经通过这种方式对其进行了配置,可以解释这些任意挂起请求?

RewriteEngine On

# Correct behaviour of IE under SSL
SetEnvIf User-Agent ".*MSIE.*" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0

SSLEngine On
SSLCertificateFile /etc/httpd/conf/ssl/_.mycert.com.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl/_. mycert.com.key
SSLCertificateChainFile /etc/httpd/conf/ssl/gd_bundle.crt

RequestHeader set X_ORIGINAL_PROTOCOL 'https'
RequestHeader set X_FORWARDED_PROTO 'https'

# Rewrite index to check for static
RewriteRule ^/$ /index.html [QSA] 
RewriteRule "^/(images|stylesheets|javascripts|system)/?(.*)" "$0" [L]

# Rewrite to check for Rails cached page
RewriteRule ^([^.]+)$ $1.html [QSA]

# Deflate
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

ExpiresActive On
<FilesMatch "\.(ico|gif|jpe?g|png|js|css)$">
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</FilesMatch>

之前是否有人遇到类似的问题?

我们的Ruby on Rails Web应用程序在RedHat Enterprise Linux 5上使用mod_rails和Apache 2.2.3运行。

更新 我现在尝试删除以下块,但问题仍然存在,所以我们可以将expires头排除在问题之外:

ExpiresActive On
<FilesMatch "\.(ico|gif|jpe?g|png|js|css)$">
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</FilesMatch>

5 个答案:

答案 0 :(得分:3)

我今天在我们的网站上调试类似的问题非常愉快。 Safari用户 - 但似乎只是Mac上的用户 - 会抱怨我们的网站在加载页面时会“随意”挂起。它通常似乎挂在一个图像上 - 完成了3个项目中的2个等等 - 但后来我在Safari,JavaScript和CSS中禁用了缓存,猜猜是什么?页面仍然挂起。

首先,关于Safari缓存的说明。即使您在“开发”菜单中选择了“禁用缓存”并从“Safari”菜单中选择了“清空缓存”,您仍然可以使用基于RAM的缓存。这意味着如果您真的想要模拟空缓存,则必须在每次请求时退出Safari,或者在按下“重新加载”按钮的同时按住Option + Shift + Prayer-To-Deity-of-Choice键。我花了一段时间才弄清楚,直到我弄明白,我一直很难重复这个问题。

原来如此!没有JavaScript,CSS或图像,你还剩下什么?除了实际的HTML之外,并不多。这就是让我了解可能与压缩相关的事实。当然,在IIS 6.0中关闭压缩会导致页面立即加载。由于IIS 6.0没有基于用户代理关闭压缩的便捷方法,因此我使用IIRF(重写URL的ISAPI筛选器)在来自Safari时重写Accept-Encoding标头:

# Safari doesn't handle gzip compression properly; we turn it off by setting 
# the q value to zero for all agents identifying themselves as Safari
RewriteCond %{HTTP_USER_AGENT} Safari
RewriteHeader Accept-Encoding: .* *;q=0

问题似乎是如果Safari正在接收静态压缩内容(即服务器发送Content-Length标题),那么Safari就可以正常处理它。但是,如果Safari正在接收动态压缩内容(也就是说,服务器正在提供由ASP.NET呈现的响应,并且内容长度在完成之前是未知的,那么服务器发送Transfer-Encoding: chunked)然后Safari进入Flaky Sir-Hangs-A-Lot模式。

为什么呢?我不知道。但这就是我如何解决它。

答案 1 :(得分:2)

奥利,

这可能相关,也可能不相关,但浏览器的同时连接数限制为2(默认情况下)。如果有连接保持打开以进行通信,并且您还要提取图像,则在浏览器释放其中一个规定连接之前,可能无法对图像进行调用。图像获取期间的挂起实际上可能是由服务器和浏览器未完成或正在保持打开的某些其他服务器连接触发的。所以你可能真的在错误的地方打猎。

如果您能够重现错误,请尝试在您的开发服务器上切换到HTTP 1.0,看看它是否解决了问题。还可以尝试将一些资产移动到另一个域/子域并从那里获取。

希望能给你另一个角度。

此致 纳拉

答案 2 :(得分:1)

在Windows中使用Safari 5.1浏览Oaracle ias 10.1.3.4服务器时的相同问题。

如果为Safari浏览器(httpd.conf)禁用了keepalive协商,问题就会消失:

BrowserMatch "Safari" nokeepalive

我不确定真正的问题是什么,或者以前的解决方案是否最好,但是此配置可以解决问题。

答案 3 :(得分:1)

我知道这是一个古老的主题,但我想分享一个Safari的解决方案,可能会节省其他时间。以下一行真正解决了所有问题:

BrowserMatch "^(?=.*Safari)(?=.*Macintosh)(?!.*Chrom).*" nokeepalive gzip-only-text/html

正则表达式确保仅检测到Mac上的Safari,而不是Mobile Safari和Chrome(ium)等。 Safari for Windows也不匹配,但keepalive问题似乎只是Mac-Safari组合。此外,一些Safari版本不能很好地处理gzip压缩的css / js。

我们网站崩溃或CSS的所有症状都不能完全加载到不同版本的Safari中,导致我几乎拔掉头发(Safari真的是新的IE)已经通过这个Apache'配置黑客'解决了。

答案 4 :(得分:0)

某些可能有所帮助的事情,没有特别的顺序:

  1. 使用资产主机,它们非常易于设置:http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html
  2. 确保尽可能在页面底部附近加载Javascript。
  3. 确保Apache / Nginx /正确设置了Expires-In HTTP标头。
  4. 在Firefox下运行Google Speed Page,这将提供很多的良好信息。