thinkphp5/tp5接口开发中跨域问题的全部解决方案,options请求的处理

版权声明:本文为博主魏永强(http://blog.csdn.net/marswill)原创文章,未经博主允许不得转载。 https://blog.csdn.net/hayixia606/article/details/82877069

场景还原:由于前后端分离后有可能出现接口的url和我们前端访问的url不再同一个域名下。这就会导致一个问题,就是浏览器的同源策略。对于同源策略如果要正常的使用我们就要处理跨域的问题。当然在跨域中接口发送前会有一次OPTIONS请求,关于为什么发送OPTIONS请求我们在正文中解释下。在tp5中解决跨域的问题,官方给出的文档是在路由中加allowCrossDomain()但是这对于我们的某些开发情况下来说不是很方便,这篇文章就是从全局解决跨域问题。用到的tp5知识点有中间件和响应的发送。

为什么发送OPTIONS请求

  1. 获取服务器支持的HTTP请求方法;
  2. 用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。

如何处理OPTIONS请求

那么可定是满足OPTIONS请求的以上两点需求即可。也就是我们要在响应中说明我们支持的http请求方法以及服务器性能,其实在PHP中我们只要用header函数来添加头部就能达到这个目的,这和框架无关。

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');

在这儿我们真实使用中可以对每个项目设置的更加具体。

tp5中如何处理

OPTIONS响应应该放在哪儿

当然我们应该把OPTIONS的请求放在请求的具体操作之前。在tp5中我们优先想到了中间件,因为我们写中间件可以让某个操作在请求的具体操作之前执行。

生成中间件

php think make:middleware CrossDomain

tp5给我们提供了这样的中间件生成cli命令你也可以手动去创建目录和CrossDomain类,记住中间件的入口方法必须是handle($request, \Closure $next)。

在handle中添加OPTIONS请求处理

<?php
/**
 * 请求处理中间件
 * Author: weiyongqiang<[email protected]>
 * Date: 2018/9/27
 * Time: 11:02
 */

namespace app\http\middleware;

use think\Response;

class CrossDomain
{
    public function handle($request, \Closure $next)
    {
        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');
        if (strtoupper($request->method()) == "OPTIONS") {
            return Response::create()->send();
        }

        return $next($request);
    }
}

需要特别注意的是在我们使用header()设置之后我们 检测请求方法如果是OPTIONS就直接返回一个200响应。这个非常重要,我在看网上其他一些资料说检测是OPTIONS请求直接exit()就行。但是明确告诉你那样会出错,应为handle必须返回一个Response,所以我们返回一个200状态的响应。

注册中间件

中间件写完必须注册了才可以生效。你可以全局注册或者在模块中注册。因为我只在api模块中需要跨域,所以我注册的是模块中间件。在api模块中创建middleware.php文件然后注册如下:

<?php
/**
 * 中间件注册
 * Author: weiyongqiang<[email protected]>
 * Date: 2018/9/27
 * Time: 11:49
 */

return [
    \app\http\middleware\CrossDomain::class
];

至此关于tp5的全局跨域问题解决,大家重点理解原理合理利用。当然开放是双刃剑必须合理利用。

猜你喜欢

转载自blog.csdn.net/hayixia606/article/details/82877069