使用 PrototypeJS 进行跨源资源共享

发布于 2024-09-13 11:18:16 字数 2099 浏览 6 评论 0原文

我在跨源资源共享和原型方面遇到一些问题。我对外部资源有一个简单的 post 请求,对于一个简单的 post 请求,必须满足一些规则:

Content-Type 必须位于 application/x-www-form-urlencoded、multipart/form-data、或 text/plain,简单请求不会使用 http 请求设置自定义标头,并且服务器必须正确设置 Access-Control-Allow-Origin 标头。

使用普通的 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 创建的标头转储:

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

以及由 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

原型使用完全不同的标头集...这导致控制台中出现以下错误:

XMLHttpRequest 无法加载foreign-host.com/bthesis/returnJSON.php。 Access-Control-Allow-Headers 不允许请求标头字段 X-Prototype-Version。 拒绝获取不安全的标头“X-JSON”

奇怪的是,Web服务器在这两种情况下都返回所请求的资源(我在chrome开发者控制台的“资源”视图中看到它),但它表明原型没有访问权限以某种方式对它

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:

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.

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.

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?


I have a dump of the Headers created by a plain JavaScript XMLHttpRequest:

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:

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"

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苏佲洛 2024-09-20 11:18:17

也许您可以在 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
    }
});

但我自己从未尝试过......
原型版本会发生什么?是发出请求后没有任何返回,还是响应被丢弃,还是什么?

Maybe you can set the origin header yourself in the Ajax Request, like so

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?

不念旧人 2024-09-20 11:18:16

我也有同样的问题。 @mplungjan 共享的链接包含答案:

您只需使用 access-control-expose-headers 让浏览器知道 x-json 标头是安全

的正在 Ruby on Rails 控制器中使用这一行

  headers['Access-Control-Expose-Headers'] = 'x-json'

(这应该很容易翻译成其他编程语言:))

有关此的更多详细信息 页面

I'm having the same problem. The link @mplungjan shared contains the answer :

You simply have to let the browser know that the x-json header is safe by using the access-control-expose-headers

I'm using this line in Ruby on Rails controller

  headers['Access-Control-Expose-Headers'] = 'x-json'

(This should be quite easy to translate into other programming languages :) )

More details on this page

深白境迁sunset 2024-09-20 11:18:16

请在此处查看 PREFLIGHT https://developer.mozilla.org/En/HTTP_access_control

问题是 Fx 对自定义标头 (X-...) 做出反应并将触发预检。
您需要让服务器返回 OPTIONS 和 POST 的所有访问控制标头,并允许自定义标头。

Please have a look at PREFLIGHT here 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.

起风了 2024-09-20 11:18:16

我在其他问题上找到了解决方案。它对我有用 - 详细信息在这里

总而言之,您需要在 Ajax.Request 中添加 onCreate 事件来删除非标准标头:

    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; 
        }); 
    }

I found solution on other SO question. And it works for me -- details are here.

To sum up -- you need onCreate event in your Ajax.Request which removes non-standard headers:

    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; 
        }); 
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文