【问题标题】:Can't send a post request when the 'Content-Type' is set to 'application/json'当“内容类型”设置为“应用程序/json”时无法发送发布请求
【发布时间】:2016-12-24 05:34:56
【问题描述】:

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

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

我什至在 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);
    });

  }

这里是相关的 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');
    }
}

我真的无法弄清楚问题所在。任何形式的帮助将不胜感激。

【问题讨论】:

标签: json reactjs cors fetch content-type


【解决方案1】:

您违反了“Same Origin Policy”。网站 www.example.com 可能永远无法从任何网站 www.example.net 加载资源,除了其自身。

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

  1. 要么将原点移至http://local.moberries.com
  2. 或将 api(您正在访问的)移动到您的本地主机。
  3. 除此之外,还有一些方法可以暂时关闭某些浏览器(尤其是 Chrome)中的此类限制,这些方法通常需要在浏览器的后续更新中付出越来越多的努力。在 Google 上搜索如何在您的浏览器版本中开启跨域资源共享。
  4. 或者,正如错误提示所暗示的,引入一个允许接收来自非来源的请求的标头。更多信息在the documentation for Access Control CORS

【讨论】:

    【解决方案2】:

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

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

    • application/x-www-form-urlencoded
    • 多部分/表单数据
    • 文本/纯文本

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

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

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

    而且一切正常。

    【讨论】:

    • 就我而言,我必须将 Content-Type 更改为 text/plain 才能使其正常工作。将这些标头添加到服务器端的 API 响应中并没有帮助。我正在使用 IBM WAS 8559。它的 API 似乎无法为 CORS 预检请求中使用的 OPTIONS 方法提供所需的响应标头。
    猜你喜欢
    • 1970-01-01
    • 2015-06-08
    • 2018-07-19
    • 1970-01-01
    • 2013-06-28
    • 2012-04-03
    • 2020-08-11
    • 1970-01-01
    相关资源
    最近更新 更多