javascript 预检响应具有无效的 HTTP 状态代码 400

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33231488/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 16:14:54  来源:igfitidea点击:

Response for preflight has invalid HTTP status code 400

javascriptjavaajaxcorsdropwizard

提问by Roy Justin

I'm trying to make a REST call (POST) using AJAX. This is my AJAX code

我正在尝试使用 AJAX 进行 REST 调用 (POST)。这是我的 AJAX 代码

<script>
var settings = {
"async": true,
"crossDomain": true,
"dataType": "json",
"url": "http://localhost:port/service/myservice",
"method": "POST",
"data": '{jsondata}',
"headers": {
      "accept": "application/json",
      "Authorization": "authValue"
  }
}

$.ajax(settings)

.done(function (response) {
  console.log(response);
});
</script>

Initially I got this error: XMLHttpRequest cannot load http://localhost:port/service/myservice. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 400.

最初我收到此错误:XMLHttpRequest 无法加载http://localhost:port/service/myservice。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'null'。响应的 HTTP 状态代码为 400。

To resolve this issue I added the following code in my dropwizard application

为了解决这个问题,我在我的 dropwizard 应用程序中添加了以下代码

Dynamic filter = env.servlets().addFilter("CORS", CrossOriginFilter.class);

filter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS");
filter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
    filter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
filter.setInitParameter("allowedHeaders", "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
filter.setInitParameter("allowCredentials", "true");

filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");

After adding this my initial exception went away, but I'm getting the following exception: XMLHttpRequest cannot load http://localhost:port/service/myservice. Response for preflight has invalid HTTP status code 400

添加此后,我的初始异常消失了,但出现以下异常:XMLHttpRequest 无法加载http://localhost:port/service/myservice。预检响应具有无效的 HTTP 状态代码 400

Is this issue related to CORS? What am I doing wrong here?

这个问题与CORS有关吗?我在这里做错了什么?

UPDATE

更新

After doing more debugging I found this behavior. When sending the request without the Authorization header I'm getting 415 (Unsupported Media Type)error.

在进行了更多调试后,我发现了这种行为。在发送没有 Authorization 标头的请求时,我收到415(不支持的媒体类型)错误。

I think something wrong with my AJAX code, can someone please help me find the issue? Thanks.

我认为我的 AJAX 代码有问题,有人可以帮我找到问题吗?谢谢。

回答by Siva Shibhi

You may try herementioned as complete answer in this thread.

您可以尝试在这里为这个线程完整的答复中提到。

$.ajax({
        type:"POST",
        beforeSend: function (request)
        {
            request.setRequestHeader("Authority", authValue);
        },
        url: "http://localhost:port/service/myservice",
        data: "json=" + escape(JSON.stringify(createRequestObject)),
        processData: false,
        success: function(msg) {
            $("#results").append("The result =" + StringifyPretty(msg));
        }
});

回答by srinivas

if you need to pass JSON data in the AJAX call, you need to specify content-type as json/application, so the server knows you are trying to send JSON data. But that will change the default content-type of the call and the call will qualify for pre-flight checking, which need proper CORS enabled client & server request.

如果您需要在 AJAX 调用中传递 JSON 数据,则需要将 content-type 指定为 json/application,以便服务器知道您正在尝试发送 JSON 数据。但这会改变调用的默认内容类型,并且调用将有资格进行飞行前检查,这需要正确的启用 CORS 的客户端和服务器请求。

For easier use case, do not use JSON.stringify() when you pass data, just make a simple string with {key:value, key:value, ...} format, and pass the string as the data. The Ajax call serializes the data by default and does the right thing, and the call stays as a single POST call to the server, where as the pre-flight mode is two calls.

为了更简单的用例,在传递数据时不要使用 JSON.stringify() ,只需使用 {key:value, key:value, ...} 格式制作一个简单的字符串,并将该字符串作为数据传递。默认情况下,Ajax 调用序列化数据并执行正确的操作,并且该调用保持为对服务器的单个 POST 调用,而预检模式是两次调用。

回答by Natural Lam

try to add the following to your settings?

尝试将以下内容添加到您的设置中?

xhrFields: { withCredentials: true }