我在跨源资源共享和原型方面遇到了一些麻烦。我对外部资源有简单的发布请求,对于简单的发布请求,必须满足一些规则:
Content-Type必须是application / x-www-form-urlencoded,multipart / form-data或text / plain,简单请求不会使用http请求设置自定义标头,并且服务器必须设置Access-Control-Allow-Origin标头正确。
使用vanilla JavaScript XMLHttpRequest一切正常但是使用PrototypeJS它将无法工作,因为它接缝Prototype设置了一些自定义标头,我不知道如何防止它。
我通过以下方式在Prototype中尝试过它:
new Ajax.Request('some.foreign-host.com/res.php', {
method: 'post',
postBody: 'foo=bar',
contentType: 'application/x-www-form-urlencoded',
onSuccess: function(e){
// some custom code
}
});
知道如何让Prototype发送这么简单的CORS请求吗?
我有一个简单的 JavaScript XMLHttpRequest 创建的Headers的转储:
POST /bthesis/returnJSON.php HTTP/1.1
Host: foreign-host.com
Connection: keep-alive
Referer: this-host.com
Content-Length: 9
Origin: this-host.com
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: */*
User-Agent: [...]
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
和原型请求创建的标题:
OPTIONS /bthesis/returnJSON.php HTTP/1.1
Host: foreign-host.com
Connection: keep-alive
Referer: this-host.com
Access-Control-Request-Method: POST
Origin: this-host.com
Access-Control-Request-Headers: X-Prototype-Version, X-Requested-With, Content-type, Accept
Accept: */*
User-Agent: [...]
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Prototype使用完全不同的标头集...导致控制台中出现以下错误:
XMLHttpRequest无法加载foreign-host.com/bthesis/returnJSON.php。请求标头字段Access-Control-Allow-Headers不允许使用X-Prototype-Version。 拒绝获得不安全的标题“X-JSON”
奇怪的是,Web服务器在两种情况下都返回所请求的资源(我在Chrome的开发者控制台的“资源”视图中看到它)但是接缝原型无法以某种方式访问它
答案 0 :(得分:11)
我遇到了同样的问题。 @mplungjan共享链接包含答案:
您只需使用x-json
access-control-expose-headers
标题是安全的
我在Ruby on Rails控制器中使用这一行
headers['Access-Control-Expose-Headers'] = 'x-json'
(这应该很容易翻译成其他编程语言:))
有关此page
的更多详情答案 1 :(得分:1)
请在https://developer.mozilla.org/En/HTTP_access_control
查看PREFLIGHT您的问题是Fx正在对自定义标题(X -...)做出反应,并会触发预检。 您需要让服务器返回OPTIONS和POST的所有访问控制标头,并让它允许自定义标头。
答案 2 :(得分:1)
我在other SO question找到了解决方案。它对我有用 - details are here。
总结一下 - 您onCreate
中需要Ajax.Request
个事件才能删除非标准标题:
onCreate: function(response) { // here comes the fix
var t = response.transport;
t.setRequestHeader = t.setRequestHeader.wrap(function(original, k, v) {
if (/^(accept|accept-language|content-language)$/i.test(k))
return original(k, v);
if (/^content-type$/i.test(k) &&
/^(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)(;.+)?$/i.test(v))
return original(k, v);
return;
});
}
答案 3 :(得分:0)
也许您可以在Ajax请求中自己设置源头,如此
new Ajax.Request('some.foreign-host.com/res.php', {
method: 'post',
postBody: 'foo=bar',
requestHeaders: {Origin: 'http://www.my.local-host.com'}
contentType: 'application/x-www-form-urlencoded',
onSuccess: function(e){
// some custom code
}
});
虽然从未尝试过...... Prototype版本会发生什么?是发出请求然后什么也没有返回,或者是被丢弃的响应,还是什么?