2

我有一个站点部署到 Heroku,我使用 Cloudflare 作为代理。

对于一些前端行为,我使用 Vue 和 Vue-resource 来执行一些 ajax 请求。响应采用带有Content-Type:application/json标头的 JSON 格式。

奇怪的是,当我的脚本出错时,因为响应没有被 vue-resource 解析为 javascript 数组/对象,尽管这是预期的行为。但是,仅当通过 Cloudflare URL 访问该站点时才会出现此问题。如果我从 Heroku url(例如 foo-bar-1234.herokuapp.com)访问它,一切正常。它在我的本地开发环境(Vagrant,Nginx)上也运行良好。

该问题也仅出现在 Chrome 中。无论它是否是 Cloudflare,它在 Safari 和 Firefox 中都可以正常工作。

我相信问题一定出在 CloudFlare 对 Heroku 服务器的响应所做的事情上,这导致 Chrome 中的 Vue 资源无法正确解析响应。

作为参考,这里是来自 CloudFlare-served 请求的响应:

cache-control:no-cache
cf-ray:2d2f1980573d3476-LHR
content-encoding:gzip
content-type:application/json
date:Mon, 15 Aug 2016 19:37:10 GMT
server:cloudflare-nginx
set-cookie:sam_session=[redacted]; expires=Mon, 15-Aug-2016 21:37:10 GMT; Max-Age=7200; path=/; HttpOnly
status:200
via:1.1 vegur
x-ratelimit-limit:60
x-ratelimit-remaining:59

与 heroku 服务的相比:

Cache-Control:no-cache
Connection:keep-alive
Content-Type:application/json
Date:Mon, 15 Aug 2016 19:40:10 GMT
Server:Apache
Set-Cookie:sam_session=[redacted]; expires=Mon, 15-Aug-2016 21:40:10 GMT; Max-Age=7200; path=/; HttpOnly
Transfer-Encoding:chunked
Via:1.1 vegur
X-Ratelimit-Limit:60
X-Ratelimit-Remaining:58

标题看起来非常相似,所以我想不出响应的不同之处会导致这种情况......

任何调试建议表示赞赏。

更新:编译的 javascript 可以在这里看到(大文件):https ://github.com/samarkanddesign/samarkand-web/blob/master/public/js/admin.js

这是一个大文件,所以最好查看 repo:https ://github.com/samarkanddesign/samarkand-web/tree/master/resources/assets/js

更新 2:在两种情况下执行的 vue-resource ajax 请求示例:

  1. CloudFlare 在此处输入图像描述

  2. 直接来自 Heroku: 在此处输入图像描述

我们可以在 heroku 示例中看到响应data被解析为一个对象数组,而在 CloudFlare 中它是一个字符串。

4

1 回答 1

3

我认为问题在于 Vue-Resource 以及 CloudFlare(SPDY 协议)使用小写响应头,而 Heroku Apache 使用大写的事实。

Vue Resource 错误地忽略了其拦截器中的小写标头,导致它无法解析响应正文。

这在这个错误问题中被引用:https ://github.com/vuejs/vue-resource/issues/317

一种快速修补它的方法是通过自定义拦截器:

Vue.http.interceptors.unshift(function(request, next) {
    next(function(response) {
        if(typeof response.headers['content-type'] != 'undefined') {
            response.headers['Content-Type'] = response.headers['content-type'];
        }
    });
});
于 2016-08-15T22:25:00.450 回答