[Lumen]对Lumen API(CORS)的跨域访问


尝试从其他域访问时返回错误

众所周知,尝试访问其他域时发生以下错误。 (跨域约束)

1
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://' is therefore not allowed access.

必须使用CORS(跨域资源共享)机制进行跨域访问

将CORS与流明一起使用

\app\Http\Middleware中创建以下文件。

CorsMiddleware.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php

namespace App\Http\Middleware;
use Closure;

class CorsMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // TODO:Access-Control-Allow-Originを適切に指定する必要がある
        $headers = [
            'Access-Control-Allow-Origin'      => '*',
            'Access-Control-Allow-Methods'     => 'POST, GET, OPTIONS', // TODO:この部分も適切に設定する必要がある
            'Access-Control-Allow-Credentials' => 'true',
            'Access-Control-Max-Age'           => '86400',
            'Access-Control-Allow-Headers'     => 'Content-Type, Authorization, X-Requested-With'
        ];

        // preflightリクエスト用
        if ($request->isMethod('OPTIONS'))
        {
            return response()->json('{"method":"OPTIONS"}', 200, $headers);
        }

        $response = $next($request);
        foreach($headers as $key => $value)
        {
            $response->header($key, $value);
        }

        return $response;
    }
}

并将以下内容添加到\bootstrap\app.php

app.php

1
2
3
$app->middleware([
    App\Http\Middleware\CorsMiddleware::class
 ]);

现在,将Access-Control-Allow-Origin添加到标题以允许跨域访问。

如果需要在生产和开发环境之间进行分隔,则应将其写入.env文件中并阅读。

.env.example

1
ACCESS_CONTROL_ALLOW_ORIGIN=*

顺便说一句,飞行前请求是在进行所需的通信之前检查其是否安全的请求。

"预检"请求首先将来自OPTIONS方法的请求发送到另一个域中的资源,以查看发送实际请求是否安全。因为站点到站点的请求会影响用户数据,所以用这种方式进行预检。

Quote:跨域资源共享(CORS)--HTTP | MDN

使用基本身份验证访问服务器上的API时

如果为

Access-Control-Allow-Origin指定通配符*,将发生以下错误。

1
2
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
Origin 'http://' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

据说您应该正确地指定

并编写它,因此您需要在Access-Control-Allow-Origin中正确描述访问目标。

CorsMiddleware.php

1
'Access-Control-Allow-Origin'      => 'http://',

如果需要其他凭据,请将Access-Control-Allow-Credentials设置为true

凭证???用于认证用户的信息的通用术语。在这里,它指的是cookie,基本身份验证ID和路径。

CorsMiddleware.php

1
'Access-Control-Allow-Credentials' => 'true',

另外,如果从JavaScript与Ajax进行通信时需要凭据,则必须在JavaScript端设置选项。
这是JavaScript(在本例中为jQuery)端的选项设置。

post.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        function sendPostToApiByAjax()
        {
            $.ajax({
                type:     "POST",
                url:      "http://",
                // username: "*****", // Basic認証用ユーザー名
                // password: "*****", // Basic認証用パスワード
                data: {
                    name : 'ajaxAPI' // リクエストパラメータ
                },
                xhrFields: {
                    withCredentials: true // クレデンシャル送るよオプション
                },
            }).done(function(data) {

                console.log('Successful communication with API!');

            }).fail(function(data) {
                console.log('Ajax fail (communication error)');
            });
        }

结束

  • CORS很难

  • Laravel应该包括barryvdh / laravel-cors(流明似乎支持它,但是没有用?)

参考

  • 如何解决流明中没有"访问控制允许来源"标题

我在

下提到的有关CORS的网站

  • 跨域资源共享(CORS)-HTTP | MDN
  • CORS摘要-Qiita
  • CORS请求需要凭据(≒cookie)时的注意事项-Qiita
  • 关于CORS(跨域资源共享)-Pape SE Blog
  • CORS要求摘要-TOEIC 940人文学科程序员