冷文学习者 - tp5
type: channel
link: https://www.kevinlu98.cn/tag/tp5/
items: ThinkPHP 5.0 解决跨域

ThinkPHP 5.0 解决跨域
type: item
date: 2021-04-16T00:02:00+08:00
description: 最近在做Freewind-Helper，就是给Feewind主题提供一些更多的功能扩展，也打算开发一些功能性API供大家调用，在开发过程中就突然想到大家可能很多时候是在前端发Ajax调API，显然，此时过来的请求是跨域请求，然后自已在网上查了些资料给大家分享一下跨域首先，大家要知道跨域是怎么产生的？同源策略跨域是因为浏览器的同源策略(浏览器上为安全性考虑实施的非常重要的安全策略)所导致何为同源？我们来看看一个URL的组成协议:\\域名\路径:端口?参数名=参数值&参数名=参数值&...其中当协议、域名、端口都相同时才算同源比如https://www.kevinlu98.cn与http://www.kevinlu98.cn这两个URL，它两协议不同，所以不同源比如https://www.kevinlu98.cn:80与https://www.kevinlu98.cn:8080这两个URL，它两的端口不同，很明显不同源比如https://www.kevinlu98.cn/aaa/bbb/ccc?name=lengwen&age=22与https://www.kevinlu98.cn这两个URL，它两只有路径与参数不一样，所以同源而浏览器的同源策略并不非是限制了发起跨域请求，而是在发起跨域请示时增加一次HTTP请求，称之为预检请求，此次请示使用OPTIONS方法发送到服务器，以获知服务器是否允许该实际请求解决方案跨域的解决有不少，大家也可以看出我在谈跨域产生的时候一直在说浏览器的同源策略，也就是说跨域请求只会在浏览器中产生拿这点来看的话我们似乎有了点解决思路可以用像NGINX 这样的服务器去做反向代理对于webpack这种项目其本身就是运行于nodejs的，而nodejs本身就不是浏览器，所以可以直接用nodejs做一层代理还有其它好多，只要这个跨域请示不是由浏览器发出的，都可以从根本解决跨域问题......这样是可以解决，但是很明显不可以解决我提出来的问题，我是想给大家去提供API接口让大家去调用，然后总不可能让调用者去解决跨域问题吧别忘了上面还提到过浏览器不限制跨域请求的发送，所以我们可以在服务端程序里去配合浏览器事先发起的预检请求来完成跨域，在服务端接收到请示时判断是否为OPTIONS方法,如果是的话返回成功状态码表明允许发起跨域请示，然后在正式请示时在response的header中加上允许跨域的信息来防止被浏览器拦截返回TP5.0解决方案在项目的application/common目录下创建behavior文件夹，在behavior中创建文件CronRun.php，写入如下代码<?php /** * @file: CronRun.php * @Author: lengwen * @Date: 2021/4/15 8:20 下午 * @Mail: kevinlu98@qq.com * @description: * */ namespace app\common\behavior; class CronRun { public function run(&$dispatch) { header("Access-Control-Allow-Origin:*"); $host_name = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : "*"; $headers = [ "Access-Control-Allow-Origin" => $host_name, "Access-Control-Allow-Credentials" => 'true', "Access-Control-Allow-Headers" => "x-token,x-uid,x-token-check,x-requested-with,content-type,Host" ]; if ($dispatch instanceof Response) { $dispatch->header($headers); } else if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { //如果是OPTIONS说明是浏览器的预检请求 $dispatch['type'] = 'response'; $response = new Response('', 200, $headers); $dispatch['response'] = $response; } } }然后在application/tags.php里进行行为扩展<?php // +-----------------------------------------------------------…