javascript 使用 PrototypeJS 实现跨源资源共享
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3413762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cross Origin Resource Sharing with PrototypeJS
提问by hans
I am having some trouble with Cross Origin Resource Sharing and Prototype. I have a simple post request to a foreign resource, and for a simple post request there are some rules that must be satisfied:
我在跨源资源共享和原型方面遇到了一些麻烦。我对外部资源有一个简单的 post 请求,对于一个简单的 post 请求,必须满足一些规则:
the Content-Type must be on of application/x-www-form-urlencoded, multipart/form-data, or text/plain, a simple request does not set custom headers with the http Request, and the Server must set the Access-Control-Allow-Origin header correct.
Content-Type 必须是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain,简单的请求不会使用 http 请求设置自定义标头,并且服务器必须设置 Access- Control-Allow-Origin 标头正确。
with a vanilla JavaScript XMLHttpRequest everything works fine but with PrototypeJS it won't work because it seams Prototype sets some custom headers and I don't know how to prevent it.
使用 vanilla JavaScript XMLHttpRequest 一切正常,但使用 PrototypeJS 它将无法工作,因为它接缝 Prototype 设置了一些自定义标头,我不知道如何防止它。
I tried it in Prototype via:
我通过以下方式在原型中尝试过:
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
}
});
Any idea how to get Prototype to send such a simple CORS Request?
知道如何让 Prototype 发送这样一个简单的 CORS 请求吗?
I have a dump of the Headers created by a plain JavaScript XMLHttpRequest:
我有一个由普通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
and the Headers created by a Prototype Request:
以及由原型请求创建的标头:
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 uses a totally different header set... which leads to following error in the console:
Prototype 使用完全不同的标头集......这导致控制台中出现以下错误:
XMLHttpRequest cannot load foreign-host.com/bthesis/returnJSON.php. Request header field X-Prototype-Version is not allowed by Access-Control-Allow-Headers. Refused to get unsafe header "X-JSON"
XMLHttpRequest 无法加载foreign-host.com/bthesis/returnJSON.php。Access-Control-Allow-Headers 不允许请求头字段 X-Prototype-Version。拒绝获取不安全的标头“X-JSON”
The strange thing is, that the Webserver returns in both cases the requested resource (I see it in the 'Resources' View of the developer console in chrome) but it seams that prototype has no access to it somehow
奇怪的是,Web 服务器在这两种情况下都返回请求的资源(我在 chrome 的开发人员控制台的“资源”视图中看到它)但它接缝该原型无法以某种方式访问它
回答by Dorian
I'm having the same problem. The link @mplungjan shared contains the answer :
我有同样的问题。@mplungjan 分享的链接包含答案:
You simply have to let the browser know that the x-jsonheader is safe by using the access-control-expose-headers
你只需要让浏览器知道x-json标题是安全的,使用access-control-expose-headers
I'm using this line in Ruby on Rails controller
我在 Ruby on Rails 控制器中使用这一行
headers['Access-Control-Expose-Headers'] = 'x-json'
(This should be quite easy to translate into other programming languages :) )
(这应该很容易翻译成其他编程语言:))
More details on this page
此页面上的更多详细信息
回答by Grzegorz Gierlik
I found solution on other SO question. And it works for me -- details are here.
我在其他 SO 问题上找到了解决方案。它对我有用——详细信息在这里。
To sum up -- you need onCreateevent in your Ajax.Requestwhich removes non-standard headers:
概括起来-你需要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;
});
}
回答by mplungjan
Please have a look at PREFLIGHT here https://developer.mozilla.org/En/HTTP_access_control
请在此处查看 PREFLIGHT https://developer.mozilla.org/En/HTTP_access_control
Your issue is that Fx is reacting to the custom headers (X-...) and will trigger preflighting. You will need to have the server return all access-control headers for OPTIONS and POST and have it allow custom headers.
您的问题是 Fx 对自定义标头 (X-...) 做出反应并将触发预检。您需要让服务器返回 OPTIONS 和 POST 的所有访问控制标头,并让它允许自定义标头。
回答by Java Drinker
Maybe you can set the origin header yourself in the Ajax Request, like so
也许你可以在 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
}
});
Never tried it myself though... What happens with the Prototype version? Is a request being issued and then nothing returns, or is a response being discarded, or what?
虽然我自己从来没有尝试过...... Prototype 版本会发生什么?是发出请求然后什么都不返回,还是响应被丢弃,或者什么?

