【问题标题】:browsers send Options instead of Post after changing http header浏览器在更改 http 标头后发送 Options 而不是 Post
【发布时间】:2012-08-17 16:24:03
【问题描述】:
/*set the response header*/
    Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers"); 
    if (responseHeaders == null) { 
        responseHeaders = new Form(); 
        responseHeaders.add("Access-Control-Allow-Origin", "*");
        responseHeaders.add("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
        getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders); 
    } 

我在我的 restlet 2.0 代码中添加了这个以允许跨域访问,这确实使第一个 GET 在页面加载时工作,但是当我稍后尝试执行 POST 时(使用主干 model.save()),浏览器发送而是使用空实体的选项。

如果我没有添加上面的代码,它确实会发送正确的 POST

这发生在 Opera、Firefox 和 Chrome 上(如果我使用 --disable-web-security 启动 chrome 可以正常工作),所以我认为这仍然是浏览器安全问题,谁能解释为什么会发生这种情况?有什么解决办法?

【问题讨论】:

    标签: http backbone.js cross-domain restlet cors


    【解决方案1】:

    来自What is the HTTP OPTIONS method?

    此方法允许客户端确定与资源相关的选项和/或要求,或服务器的功能,而无需暗示资源操作或启动资源检索。

    我曾多次与 CORS 问题作斗争,我总是用 try and error 的方法解决它们,我对您的情况的建议是将 OPTIONS 添加到您的允许方法

    "Access-Control-Allow-Methods": "POST, GET, PUT, DELETE, OPTIONS"
    

    并让您的服务器使用* 响应OPTIONS 请求,在Sinatra 中是这样的:

    options "/*" do
      "*"
    end
    

    更新

    关于错误header field Content-Type is not allowed by Access-Control-Allow-Headers.的评论中解释的新问题

    尝试添加另一个 CORS 标头:

    "Access-Control-Allow-Headers": "origin, x-requested-with, content-type"
    

    【讨论】:

    • 在我添加选项标头并返回 json 表示后,我得到:Access-Control-Allow-Headers 不允许请求标头字段 Content-Type。我真的不了解 Sinatra,有什么建议可以在 Restlet 中做到这一点吗?
    【解决方案2】:

    感谢 fguillen 的建议,用谷歌搜索我找到了可行的方法

    /*set the response header*/
        Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers"); 
        if (responseHeaders == null) { 
            responseHeaders = new Form(); 
            responseHeaders.add("Access-Control-Allow-Origin", "*");
            responseHeaders.add("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS"); 
            responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
            getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders); 
        } 
    

    所以这是在 Restlet 2.0 中为 cors 注入的正确代码 不要错过 responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");至少在您处理骨干时

    【讨论】:

      【解决方案3】:

      有点偏离主题,但我认为它可能对某人有用并节省时间。
      我遇到了 uwsgi 服务器和 backboneCORS 问题。这是我的 uwsgi.ini 文件的一部分,它似乎适用于 POST。

      [uwsgi]
      add-header = Access-Control-Allow-Origin: *
      add-header = Access-Control-Allow-Headers: origin, x-requested-with, content-type                                                                 
      add-header = Access-Control-Allow-Methods: POST,GET,PUT,OPTIONS,DELETE
      add-header = Content-Type: application/json; charset=UTF-8
      add-header = Accept: application/json
      

      如 fguillen 所述,服务器需要回复 '*' 以获取 OPTIONS 请求。

      【讨论】:

        【解决方案4】:

        以下代码可用于解决 Restlet 2.0 中的跨域问题

        Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers"); 
        if (responseHeaders == null) { 
            responseHeaders = new Form(); 
            getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders); 
        } 
        responseHeaders.add("Access-Control-Allow-Origin", "*"); 
        responseHeaders.add("Access-Control-Allow-Methods", "GET,DELETE,PUT,POST,OPTIONS");
        responseHeaders.add("Access-Control-Allow-Headers", "Content-Type"); 
        responseHeaders.add("Access-Control-Allow-Credentials", "false"); 
        responseHeaders.add("Access-Control-Max-Age", "60");
        

        【讨论】:

          【解决方案5】:

          也许此链接可以为您提供一些关于 CORS 工作原理及其在 Restlet 中的支持CorsFilter 的提示:

          希望对你有帮助, 蒂埃里

          【讨论】:

            【解决方案6】:

            在不同的内容上,下面给出的代码适用于 Restlet 2.1 以上。

            import org.restlet.engine.header.Header;
            
            
            
            private static final String HEADERS_KEY = "org.restlet.http.headers";
            
            
            
            @SuppressWarnings("unchecked")
            
            static Series<Header> getMessageHeaders(Message message) {
            
            ConcurrentMap<String, Object> attrs = message.getAttributes();
            
            Series<Header> headers = (Series<Header>) attrs.get(HEADERS_KEY);
            
            if (headers == null) {
            
                     headers = new Series<Header>(Header.class);
            
                 Series<Header> prev = (Series<Header>) 
            
                      attrs.putIfAbsent(HEADERS_KEY, headers);
            
                if (prev != null) { headers = prev; }
            
                 }
            
               return headers;
            

            }

            //The JSON Query "GET"
            @Get("json")
            
             public Representation toJson()
            
              {
            
               getMessageHeaders(getResponse()).add("Access-Control-Allow-Origin", "*"); 
            
               getMessageHeaders(getResponse()).add("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
            
               getMessageHeaders(getResponse()).add("Access-Control-Allow-Headers", "x-requested-with,Content-Type"); 
            
               getMessageHeaders(getResponse()).add("Access-Control-Allow-Credentials", "true"); 
            
               getMessageHeaders(getResponse()).add("Access-Control-Max-Age", "60"); 
            
              return get();
            }
            

            【讨论】:

              猜你喜欢
              • 2013-05-14
              • 1970-01-01
              • 2015-07-27
              • 2017-12-06
              • 2016-06-14
              • 2019-02-03
              • 2010-09-28
              • 1970-01-01
              相关资源
              最近更新 更多