'Content-Type' 设置为 'application/json' 时无法发送 post 请求
Can't send a post request when the 'Content-Type' is set to 'application/json'
我正在开发 React 应用程序,我正在使用 fetch 发送请求。我最近制作了一个注册表单,现在我正在将它与 API 集成。以前 API 接受 url 编码数据并且一切正常。但是现在要求已经改变并且 API 接受 JSON 中的数据,我不得不将 content-type header 从 '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.
我什至在 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');
}
}
我实在想不通。任何形式的帮助将不胜感激。
您违反了“Same Origin Policy”。网站 www.example.com 可能永远无法从除自身以外的任何网站 www.example.net 加载资源。
然而,在开发过程中,有时需要能够做到这一点。要绕过这个:
- 要么将您的原点移至 http://local.moberries.com,
- 或将 api(您正在访问的)移动到您的本地主机。
- 除此之外,在某些浏览器中(尤其是Chrome),还有一些方法可以暂时关闭这些限制,这些方法通常需要在浏览器的后续更新中付出越来越多的努力。搜索 Google 如何在您的浏览器版本中打开 Cross-Origin 资源共享。
- 或者,如错误提示所示,引入一个 header 允许接受来自 non-origins 的请求。更多信息在 the documentation for Access Control CORS
事实证明,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
要将内容类型设置为 'application/json',我必须在 API 中设置自定义内容类型 header。刚刚删除了最后一个 header 并添加了这个:
->header('Access-Control-Allow-Headers', 'Content-Type');
一切正常。
我正在开发 React 应用程序,我正在使用 fetch 发送请求。我最近制作了一个注册表单,现在我正在将它与 API 集成。以前 API 接受 url 编码数据并且一切正常。但是现在要求已经改变并且 API 接受 JSON 中的数据,我不得不将 content-type header 从 '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.
我什至在 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');
}
}
我实在想不通。任何形式的帮助将不胜感激。
您违反了“Same Origin Policy”。网站 www.example.com 可能永远无法从除自身以外的任何网站 www.example.net 加载资源。
然而,在开发过程中,有时需要能够做到这一点。要绕过这个:
- 要么将您的原点移至 http://local.moberries.com,
- 或将 api(您正在访问的)移动到您的本地主机。
- 除此之外,在某些浏览器中(尤其是Chrome),还有一些方法可以暂时关闭这些限制,这些方法通常需要在浏览器的后续更新中付出越来越多的努力。搜索 Google 如何在您的浏览器版本中打开 Cross-Origin 资源共享。
- 或者,如错误提示所示,引入一个 header 允许接受来自 non-origins 的请求。更多信息在 the documentation for Access Control CORS
事实证明,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
要将内容类型设置为 'application/json',我必须在 API 中设置自定义内容类型 header。刚刚删除了最后一个 header 并添加了这个:
->header('Access-Control-Allow-Headers', 'Content-Type');
一切正常。