【问题标题】:Cross Origin Resource Sharing with PrototypeJS使用 PrototypeJS 进行跨域资源共享
【发布时间】:2011-03-25 17:36:34
【问题描述】:

我在使用跨域资源共享和原型时遇到了一些问题。我有一个对外部资源的简单发布请求,对于一个简单的发布请求,必须满足一些规则:

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

以及由原型请求创建的标头:

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 的开发者控制台的“资源”视图中看到它),但它表明原型无法以某种方式访问​​它

【问题讨论】:

    标签: javascript prototypejs ajax.request cors


    【解决方案1】:

    我在other SO question 上找到了解决方案。它对我有用——details are here

    总而言之——您需要在 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; 
            }); 
        }
    

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      更多详情page

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 2011-12-25
            • 2013-11-24
            • 2011-05-07
            • 2012-07-12
            • 2011-03-27
            • 2017-10-06
            • 2013-01-12
            • 2014-04-23
            相关资源
            最近更新 更多