$ .ajax post请求头字段Content-Type不允许CORS

时间:2017-04-18 05:25:31

标签: javascript jquery json ajax

我在发出CORS请求时收到以下错误。有趣的是,这是在野生动物园工作,但不是谷歌chrome和Firefox。我一直在浏览所有内容,但没有在网上找到任何解决方案。

我正在尝试将json发送到服务器,但据我所知,我需要在将其发送到服务器之前使其成为字符串,因此我使用的是JSON.stringify,但最后我期待服务器的json结果。 / p>

这就是我在卷曲电话上的表现。 (我只是试着看看标题)

HTTP/1.1 200 OK
Date: Tue, 18 Apr 2017 15:13:04 GMT
Server: Apache
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Max-Age: 21600
Content-Length: 213
Content-Type: application/json

这就是我在chrome

中的网络标签上获得的内容

network tab

最后一部分是我的代码

    function foo(api_key, url, query, pdata, callback) {
        var result = 'none';
        if (typeof pdata != "undefined"){
            var mydata = {"api_key": api_key, "query": query, "data": pdata };
        }
        else {
            var mydata = {"api_key": api_key, "query": query};
        }
        $.ajax({
               method : "POST",
               url : url,
               data: JSON.stringify(mydata),
               contentType: "application/json;charset=UTF-8",
               cache: false,
               dataType: "json",
               success : function(data) {
               console.log("API call is working successfully!")
               callback(data);
               result = data  
         },
         error: function( data, status, error ) { 
               console.log("API call failed!")
         }
     });
     return result;
    }

这是我得到的错误。

XMLHttpRequest cannot load https://my_url. Request header field   Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
api.js:29 API call failed!`

我应该怎么做,更改或添加以使其在chrome和firefox中运行?

3 个答案:

答案 0 :(得分:5)

您的ajax请求似乎是正确的,但问题出在服务器端。对于每个cors请求,浏览器都会发送预检请求。只有在预检请求通过服务器端验证后,您才能发送cors ajax请求。

因此,根据您用于预检请求的服务器类型,您需要向浏览器发送正确的响应。

正确的回复意味着在预检请求的响应中设置适当的标题并将其发送回客户端,即浏览器。

对于curl请求,您不需要这样做,因为curl请求不会通过服务器端的预检请求验证。

出于安全原因,仅在浏览器的情况下才需要它。

一个例子可能是这样的 -

    HttpResponse response = new HttpResponse(request.getProtocolVersion(), NO_CONTENT);
    HttpHeaders headers = response.headers();

    headers.set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
    headers.set(CONTENT_TYPE, "text/plain; charset=UTF-8");
    headers.set(CACHE_CONTROL, "max-age=31536000, public");
    headers.set(ACCESS_CONTROL_ALLOW_ORIGIN, request.headers().get("Origin"));
    headers.set(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    headers.set(ACCESS_CONTROL_MAX_AGE, "31536000");
    headers.set(ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, OPTIONS");
    headers.set(ACCESS_CONTROL_ALLOW_HEADERS, request.headers().get("Access-Control-Request-Headers"));
    headers.set(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    send(response);

这只是一个例子,但是你将如何做到这一点完全取决于你正在使用的服务器端和服务器框架。

答案 1 :(得分:0)

实际上,您的preflight请求失败了,因为您设置了content-type但是,响应时没有Content-Type标头。

因此,要么不将content-type设置为json,请使用text/plain, form-data来绕过预检请求,并直接将ajax请求发送到跨域服务器。

或在服务器上设置Access-Control-Allow-Headers:Content-Type标头。

在apache上设置标题

Header set Access-Control-Allow-Headers "Content-Type"

会奏效。

enter image description here

答案 2 :(得分:0)

问题解决了!客户端的一切都是正确的

开始在服务器上使用CORS lib

from flask_cors import CORS 

并且@WitVault说用这些设置配置服务器解决了我的问题!

cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
app.config['CORS_HEADERS'] = 'Content-Type'