Rumah > rangka kerja php > ThinkPHP > 解析thinkphp withCredentials跨域问题解决思路

解析thinkphp withCredentials跨域问题解决思路

藏色散人
Lepaskan: 2021-02-17 09:22:29
ke hadapan
2156 orang telah melayarinya

解析thinkphp withCredentials跨域问题解决思路


thinkphp withCredentials 跨域问题解决思路

跨域是什么这里就不细讲, 这里主要是thinkphp5.1, 说一下大概的解决思路

首先,因为前端是自己写的, 在axios配置中, 我设置了如下

withCredentials: true // 跨域请求时发送cookie

// 创建一个axios
const service = axios.create({
  baseURL: URL , 
  withCredentials: true, // 跨域请求时发送cookie
  timeout: 5000 // request timeout
})
Salin selepas log masuk

在后端的配置中,配置的是

header("Access-Control-Allow-Origin: *");
Salin selepas log masuk

故而抛出了这样一个错误

Access to XMLHttpRequest at 'http://store.ink/admin/me?sid=lbn3mpacfb3k1mbehnk9qh8kf3' from origin 'http://vue-admin-web.ink' has been blocked by CORS policy: 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'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Salin selepas log masuk

意思大概为 设置 withCredentialstrue 时, origin 是不允许为 *的, origin必须设置为来源的地址

也就是 http://a.com 请求 http://b.com 的时候, http://a.com 必须设置origin 为 http://b.com 才能通过

最后参阅配置如下

 $origin = $_SERVER['HTTP_ORIGIN'] ?? '*';
        header("Access-Control-Allow-Origin: $origin");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
        header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
        header('Access-Control-Max-Age: 1728000');
Salin selepas log masuk

当然, 为 * 的时候也可以这样

header("Access-Control-Allow-Origin: *");
        header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
        header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
        header('Access-Control-Max-Age: 1728000');
Salin selepas log masuk

首先 定义个中间件 php think make:middleware CrossDomain

<?php
namespace app\http\middleware;

use think\Response;


class CrossDomain
{
    public function handle($request, \Closure $next)
    {
        $origin = $_SERVER[&#39;HTTP_ORIGIN&#39;] ?? &#39;*&#39;;
        header("Access-Control-Allow-Origin: $origin");
        header(&#39;Access-Control-Allow-Credentials: true&#39;);
        header(&#39;Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With&#39;);
        header(&#39;Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE&#39;);
        header(&#39;Access-Control-Max-Age: 1728000&#39;);

        return $next($request);
    }
}
Salin selepas log masuk

router.php

Route::group(&#39;&#39;, function (){
    ....
    这里写路由
    ....
})->middleware(['CrossDomain']);
Salin selepas log masuk

然后又有一个新问题

因为如上是走的路由文件,当请求的url匹配路由的时候, 会走跨域中间件, 当大家都知道的是, delete 和 put 等方法是会提前发起一个options请求的, 也就是无法匹配路由文件,无法走跨域中间件

故而:

定义一个 错误异常接管 https://www.kancloud.cn/manual/thinkphp5_1/354092#_42

....
public function render(Exception $e)
{
    # 这里来处理跨域问题 
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '*';
    header("Access-Control-Allow-Origin: $origin");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
    header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
    header('Access-Control-Max-Age: 1728000');
    $type = request()->isAjax() ? 'json' : "html";
    $response = \think\response\Json::create([], $type, 200, []);
    return $response; # response  // 在异常处理接管中,必须返回的是一个人response响应, 而不是 `throw new `抛出一个响应
}
...
Salin selepas log masuk

完成。

Atas ialah kandungan terperinci 解析thinkphp withCredentials跨域问题解决思路. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:segmentfault.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan