2016-08-17 66 views
8

我正在使用React应用程序,并使用提取发送请求。我最近做了一个注册表单,现在我正在将它与它的API进行整合。以前API接受的URL编码数据,它都工作正常。但现在需求已经改变,API以JSON接受数据,我不得不将内容类型的头从'application/x-www-form-urlencoded'改为'application/json'。但我得到以下错误:'Content-Type'设置为'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.

我甚至设置的访问控制允许报头'的API中,但它仍然无法正常工作。下面是客户端的相关代码:

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'); 
    } 
} 

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

+0

http://local.moberries.com/api/v1/candidate无法访问 –

+2

因为它是本地的。您无法访问它。 –

回答

11

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

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

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

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

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

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

它工作都很好。

+0

在我的情况下,我不得不将'Content-Type'改为'text/plain'以使其工作。将这些标头添加到服务器端的API响应中并没有帮助。我正在使用IBM WAS 8559.它的API似乎无法为CORS预查询请求中使用的“OPTIONS”方法提供所需的响应头。 –

0

您正在违反'Same Origin Policy'。网站www.example.com可能永远无法从任何网站www.example.net加载资源,除非它本身。

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

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