不允许 Lumen API CORS Ajax 405 方法 [英] Lumen API CORS Ajax 405 Method Not Allowed
问题描述
我在 Laravel Lumen 上有一个 api,我们通过 Postman 和 Ruby Rest Client 进行测试,一切顺利,但我们创建了一个简单的 Auth Login 来响应网络令牌,一切正常,但在我们的 React App 上实际上我们有这个405 405 方法不允许".
I have an api on Laravel Lumen, we test via Postman and Ruby Rest Client and all go very well, but we create a simple Auth Login that response a web token, all works fine but on our React App actually we have this "405 405 Method Not Allowed".
我们用下面的代码创建一个类:
We create a class with the next code:
<?php namespace palaniklumenMiddleware;
use Closure;
use IlluminateHttpResponse;
class LumenCors {
protected $settings = array(
'origin' => '*', // Wide Open!
'allowMethods' => 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS',
);
protected function setOrigin($req, $rsp) {
$origin = $this->settings['origin'];
if (is_callable($origin)) {
// Call origin callback with request origin
$origin = call_user_func($origin,
$req->header("Origin")
);
}
$rsp->header('Access-Control-Allow-Origin', $origin);
}
protected function setExposeHeaders($req, $rsp) {
if (isset($this->settings['exposeHeaders'])) {
$exposeHeaders = $this->settings['exposeHeaders'];
if (is_array($exposeHeaders)) {
$exposeHeaders = implode(", ", $exposeHeaders);
}
$rsp->header('Access-Control-Expose-Headers', $exposeHeaders);
}
}
protected function setMaxAge($req, $rsp) {
if (isset($this->settings['maxAge'])) {
$rsp->header('Access-Control-Max-Age', $this->settings['maxAge']);
}
}
protected function setAllowCredentials($req, $rsp) {
if (isset($this->settings['allowCredentials']) && $this->settings['allowCredentials'] === True) {
$rsp->header('Access-Control-Allow-Credentials', 'true');
}
}
protected function setAllowMethods($req, $rsp) {
if (isset($this->settings['allowMethods'])) {
$allowMethods = $this->settings['allowMethods'];
if (is_array($allowMethods)) {
$allowMethods = implode(", ", $allowMethods);
}
$rsp->header('Access-Control-Allow-Methods', $allowMethods);
}
}
protected function setAllowHeaders($req, $rsp) {
if (isset($this->settings['allowHeaders'])) {
$allowHeaders = $this->settings['allowHeaders'];
if (is_array($allowHeaders)) {
$allowHeaders = implode(", ", $allowHeaders);
}
}
else { // Otherwise, use request headers
$allowHeaders = $req->header("Access-Control-Request-Headers");
}
if (isset($allowHeaders)) {
$rsp->header('Access-Control-Allow-Headers', $allowHeaders);
}
}
protected function setCorsHeaders($req, $rsp) {
// http://www.html5rocks.com/static/images/cors_server_flowchart.png
// Pre-flight
if ($req->isMethod('OPTIONS')) {
$this->setOrigin($req, $rsp);
$this->setMaxAge($req, $rsp);
$this->setAllowCredentials($req, $rsp);
$this->setAllowMethods($req, $rsp);
$this->setAllowHeaders($req, $rsp);
}
else {
$this->setOrigin($req, $rsp);
$this->setExposeHeaders($req, $rsp);
$this->setAllowCredentials($req, $rsp);
}
}
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next) {
if ($request->isMethod('OPTIONS')) {
$response = new Response("", 200);
}
else {
$response = $next($request);
}
$this->setCorsHeaders($request, $response);
return $response;
}
}
我们在 bootstrap/app.php 上添加
We add on bootstrap/app.php
$app->routeMiddleware([
'auth' => AppHttpMiddlewareAuthenticate::class,
'cors' => palaniklumenMiddlewareLumenCors::class,
]);
还有我们的路线:
$app->group(['middleware' => 'cors'], function($app)
{
$app->post('/auth/login', function() {
return response()->json([
'message' => 'CORS OPTIONS Accepted.',
]);
});
});
我们的其余客户端一切正常,但我在我们的 React js 应用程序中是怎么说的,因为浏览器发送了一个 OPTIONS,请求不会传递到 POST.
With our rest clients all goes fine but how i said on our React js app because the browser send an OPTIONS, the request doesn't pass to the POST.
我们的 Recat Axios 请求:
Our Recat Axios request:
axios({
method: 'post',
url: 'URL',
data: {
email: 'Fred',
password: 'Flintstone'
}
}).then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
错误 con React 日志:问题是 OPTIONS 在浏览器的 POST 之前发送.标题响应:HTTP/1.1 405 方法不允许允许:发布缓存控制:无缓存,私有内容类型:文本/html;字符集=UTF-8日期:2017 年 10 月 29 日星期日 01:30:34 GMT服务器:Apache/2.4.18 (Ubuntu)传输编码:分块连接:保持活动
Error con React log: The problem is that OPTIONS is send before POST for the browser. Headers response: HTTP/1.1 405 Method Not Allowed Allow: POST Cache-Control: no-cache, private Content-Type: text/html; charset=UTF-8 Date: Sun, 29 Oct 2017 01:30:34 GMT Server: Apache/2.4.18 (Ubuntu) transfer-encoding: chunked Connection: keep-alive
我们的 API 缺少什么?
What are we missing on our API?
问候.
推荐答案
React 在发送原始请求之前,会发送一个 Http 方法 Options 的请求,用于检查 API 服务器是否接受跨域请求?
Before sending the original request, React sends a request of Http method Options which checks if cross-domain requests are accepted at the API server?
以下是我遵循的方法:
添加方法option
Route::options(
'/{any:.*}',
[
'middleware' => ['CorsMiddleware'],
function (){
return response(['status' => 'success']);
}
]
);
CorsMiddleware
是用于处理请求的中间件.
CorsMiddleware
is the middleware used to handle the requests.
<?php
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpResponse;
class CorsMiddleware
{
protected $settings = array(
'origin' => '*', // Wide Open!
'allowMethods' => 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS',
);
protected function setOrigin($req, $rsp) {
$origin = $this->settings['origin'];
if (is_callable($origin)) {
// Call origin callback with request origin
$origin = call_user_func($origin,
$req->header("Origin")
);
}
$rsp->header('Access-Control-Allow-Origin', $origin);
}
protected function setExposeHeaders($req, $rsp) {
if (isset($this->settings['exposeHeaders'])) {
$exposeHeaders = $this->settings['exposeHeaders'];
if (is_array($exposeHeaders)) {
$exposeHeaders = implode(", ", $exposeHeaders);
}
$rsp->header('Access-Control-Expose-Headers', $exposeHeaders);
}
}
protected function setMaxAge($req, $rsp) {
if (isset($this->settings['maxAge'])) {
$rsp->header('Access-Control-Max-Age', $this->settings['maxAge']);
}
}
protected function setAllowCredentials($req, $rsp) {
if (isset($this->settings['allowCredentials']) && $this->settings['allowCredentials'] === True) {
$rsp->header('Access-Control-Allow-Credentials', 'true');
}
}
protected function setAllowMethods($req, $rsp) {
if (isset($this->settings['allowMethods'])) {
$allowMethods = $this->settings['allowMethods'];
if (is_array($allowMethods)) {
$allowMethods = implode(", ", $allowMethods);
}
$rsp->header('Access-Control-Allow-Methods', $allowMethods);
}
}
protected function setAllowHeaders($req, $rsp) {
if (isset($this->settings['allowHeaders'])) {
$allowHeaders = $this->settings['allowHeaders'];
if (is_array($allowHeaders)) {
$allowHeaders = implode(", ", $allowHeaders);
}
}
else { // Otherwise, use request headers
$allowHeaders = $req->header("Access-Control-Request-Headers");
}
if (isset($allowHeaders)) {
$rsp->header('Access-Control-Allow-Headers', $allowHeaders);
}
}
protected function setCorsHeaders($req, $rsp) {
// http://www.html5rocks.com/static/images/cors_server_flowchart.png
// Pre-flight
if ($req->isMethod('OPTIONS')) {
$this->setOrigin($req, $rsp);
$this->setMaxAge($req, $rsp);
$this->setAllowCredentials($req, $rsp);
$this->setAllowMethods($req, $rsp);
$this->setAllowHeaders($req, $rsp);
}
else {
$this->setOrigin($req, $rsp);
$this->setExposeHeaders($req, $rsp);
$this->setAllowCredentials($req, $rsp);
}
}
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next) {
if ($request->isMethod('OPTIONS')) {
$response = new Response("", 200);
}
else {
$response = $next($request);
}
$this->setCorsHeaders($request, $response);
return $response;
}
}
加载中间件 $app->routeMiddleware
bootstrap/app.php
保持组中的所有应用程序 URL 检查 CorsMiddleware
Keep all application URLs in the group checking the CorsMiddleware
Route::group(['middleware' => 'CorsMiddleware'], function($router){
$app->post('/auth/login', function() {
return response()->json([
'message' => 'CORS OPTIONS Accepted.',
]);
});
}
这篇关于不允许 Lumen API CORS Ajax 405 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!