当“Content-Type”设置为“application/json”时无法发送发布请求

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

Can't send a post request when the 'Content-Type' is set to 'application/json'

jsonreactjscorsfetchcontent-type

提问by Arslan Tariq

I am working on a React application and I am using fetch to send a request. I have made a Sign Up form recently and now I am integrating it with it's API. Previously the API accepted url encoded data and it was all working fine. but now that the requirement has changed and the API accepts data in JSON, I had to change the content-type header from 'application/x-www-form-urlencoded' to 'application/json'. But I get the following error:

我正在开发一个 React 应用程序,我正在使用 fetch 发送请求。我最近制作了一个注册表单,现在我正在将它与它的 API 集成。以前 API 接受 url 编码的数据,并且一切正常。但是现在需求已经改变并且 API 接受 JSON 中的数据,我不得不将内容类型标头从“application/x-www-form-urlencoded”更改为“application/json”。但我收到以下错误:

Fetch API cannot load http://local.moberries.com/api/v1/candidate. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Fetch API 无法加载http://local.moberries.com/api/v1/candidate。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问Origin ' http://localhost:3000'。如果不透明响应满足您的需求,请将请求的模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

I have even set the 'Access-Control-Allow-Headers' in the API but it still doesn't work. Here is the relevant code for the client side:

我什至在 API 中设置了“Access-Control-Allow-Headers”,但它仍然不起作用。这是客户端的相关代码:

sendFormData() {
    let {user} = this.props;

    var formData = {
      first_name: ReactDOM.findDOMNode(this.refs.firstName).value,
      last_name: ReactDOM.findDOMNode(this.refs.lastName).value,
      city: ReactDOM.findDOMNode(this.refs.currentCity).value,
      country: ReactDOM.findDOMNode(this.refs.currentCountry).value,
      is_willing_to_relocate: user.selectedOption,
      cities: relocateTo,
      professions: opportunity,
      skills: skills,
      languages: language,
      min_gross_salary: minSal,
      max_gross_salary: maxSal,
      email: ReactDOM.findDOMNode(this.refs.email).value,
      password: ReactDOM.findDOMNode(this.refs.password).value
    };

    var request = new Request('http://local.moberries.com/api/v1/candidate', {
      method: 'POST',
      mode: 'cors',
      headers: new Headers({
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      })
    });

    var requestBody = JSON.stringify(formData);

    console.log(requestBody);

    fetch(request, {body: requestBody})
      .then(
        function (response) {
          if (response.status == 200 || response.status == 201) {
            return response.json();
          } else {
            console.log('Failure!', response.status);
          }
        }).then(function (json) {

      var responseBody = json;

      console.log(typeof responseBody, responseBody);
    });

  }

And here is the relevant API code:

这是相关的 API 代码:

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', '*')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
            ->header('Access-Control-Allow-Headers: Origin, Content-Type, application/json');
    }
}

I really can't figure out the problem. Any kind of help will be appreciated.

我实在想不通问题所在。任何形式的帮助将不胜感激。

回答by Arslan Tariq

It turns out that CORS only allows some specific content types.

事实证明,CORS 只允许某些特定的内容类型。

The only allowed values for the Content-Type header are:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Content-Type 标头的唯一允许值是:

  • 应用程序/x-www-form-urlencoded
  • 多部分/表单数据
  • 文本/普通

Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

来源:https: //developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

To set the content type to be 'application/json', I had to set a custom content type header in the API. Just removed the last header and added this one:

要将内容类型设置为“application/json”,我必须在 API 中设置自定义内容类型标头。刚刚删除了最后一个标题并添加了这个:

->header('Access-Control-Allow-Headers', 'Content-Type');

and it is working all good.

它运行良好。

回答by Abdul Wasae

You are violating the 'Same Origin Policy'. A website www.example.com may never be able to load resources from any website www.example.net other than from itself.

您违反了“同源政策”。网站 www.example.com 可能永远无法从任何网站 www.example.net 加载资源,而不是从其自身加载资源。

During development however, sometimes one needs to be able to do that. To bypass this:

然而,在开发过程中,有时需要能够做到这一点。要绕过这个:

  1. either move your origin to http://local.moberries.com,
  2. or move the api (which you are accessing) to your localhost.
  3. Other than that, there are ways to temporarily turn off restrictions of these kinds in some browsers (esp. Chrome), methods of which usually require more and more effort in the subsequent updates of the browser. Search Google about how to turn on Cross-Origin Resource Sharing in your version of the browser.
  4. Or, as the error prompt suggests, introduce a header allowing requests to be entertained from non-origins. More information is in the documentation for Access Control CORS
  1. 要么将您的来源移动到http://local.moberries.com
  2. 或将 api(您正在访问的)移动到您的本地主机。
  3. 除此之外,还有一些方法可以暂时关闭某些浏览器(尤其是Chrome)中的此类限制,这些方法通常需要在浏览器的后续更新中付出更多努力。在 Google 上搜索有关如何在您的浏览器版本中打开跨域资源共享的信息。
  4. 或者,正如错误提示所暗示的那样,引入一个标题,允许来自非来源的请求。更多信息在访问控制 CORS 的文档中