我用laravel写后端。并尝试使用IONIC来调用api @angular/http
。
在后端服务器中,我已经在中间件和响应中添加了Access-Control-Allow-Origin
。
中间件。
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
->header('Access-Control-Allow-Credentials', true)
->header('Access-Control-Allow-Headers', 'Content-Type')
->header('Vary', 'Origin');
响应。
return response($data, 200)
->withHeaders([
'Content-Type' => 'application/json',
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Credentials' => true,
'Access-Control-Allow-Headers' => 'Content-Type',
'Vary' => 'Origin',
]);
离子
url: any = 'http://myurl.local/api/';
headers = new Headers(
{
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Access-Control-Request-Methods' : 'POST'
});
options = new RequestOptions({ headers: this.headers });
login(username, password) {
let data = JSON.stringify({
username : username,
password : password
});
let fullUrl = this.url+'login';
return new Promise((resolve, reject) => {
this.http.post(fullUrl, data, this.options)
.toPromise()
.then((response) =>
{
console.log('API Response : ', response);
resolve(response.json());
})
.catch((error) =>
{
console.error('API Error : ', error.toString());
reject(error.json());
});
});
}
当我使用'Content-Type' : 'application/json'
调用api时,它总是响应错误。
XMLHttpRequest无法加载http://myurl.local/api/login。回应 预检请求未通过访问控制检查:否 '访问控制允许来源'标题出现在请求的上 资源。起源' http://localhost:8100'因此是不允许的 访问。
但如果我将'Content-Type'
更改为'application/x-www-form-urlencoded'
。我没有收到任何错误。
但是当我试图看到输入$request->all()
时。我得到的数据是'{"username":"XXXXXXXXXX","password":"XXXXXXXXXX"}' => NULL
。
邮差很好。我真的尝试了很多方法来解决这个问题,但我不能。
有什么不对?
答案 0 :(得分:4)
Yeahhhh !!!最后,我可以解决这个问题。该死的。
在中间件中。
public function handle($request, Closure $next)
{
if ($request->getMethod() == "OPTIONS") {
return response(['OK'], 200)
->withHeaders([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Credentials' => true,
'Access-Control-Allow-Headers' => 'Authorization, Content-Type',
]);
}
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
->header('Access-Control-Allow-Credentials', true)
->header('Access-Control-Allow-Headers', 'Authorization, Content-Type');
}
在IONIC中更改标题为。
headers = new Headers(
{
'Content-Type' : 'application/json'
});
在添加options
路由后,它才会生效。 (就我而言,因为我没有使用Route::resource
)
Route::group(['middleware' => 'AddHeader'], function()
{
Route::post('/login', 'LoginController@index');
Route::options('/login', 'LoginController@index');
});
PS。我在function index()
中有一些逻辑,我尝试使用__construct()
。但它不起作用。
答案 1 :(得分:1)
在处理请求的Laravel代码中,您需要为OPTIONS
个请求添加处理:
if ($request->getMethod() == "OPTIONS") {
$headers = [
'Access-Control-Allow-Origin' => '*'
'Access-Control-Allow-Methods'=> 'POST, GET',
'Access-Control-Allow-Headers'=> 'Content-Type'
];
return Response::make('OK', 200, $headers);
}
当我使用
'Content-Type' : 'application/json'
调用api时,它总是响应错误。但如果我将
'Content-Type'
更改为'application/x-www-form-urlencoded'
。我没有收到任何错误。
application/json
内容类型触发浏览器执行CORS预检OPTIONS
请求。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests有更多详情。
邮差很好。
邮差可以不受限制地自由地提出跨域请求。但浏览器不允许您的前端JavaScript代码访问来自跨源请求的响应,除非响应指示发送请求的服务器正在选择接收跨源请求。
如果您的请求是触发浏览器执行CORS预检OPTIONS
请求的请求,则请求发送到的服务器必须配置为以正确的方式响应OPTIONS
请求。这就是为什么您需要在Laravel代码中为OPTIONS
请求添加额外处理。
如果服务器没有以正确的方式响应OPTIONS
预检,那么浏览器将停在那里,并且永远无法执行您实际尝试发送的POST
请求。< / p>