冷文学习者

文章 分类 标签
22 7 36

公告

冷文博客(KEVINLU98.COM),记录我日常业余的一点一滴。
利用业余时间写与typecho与emlog的主题、插件等,同时也分享一些资源与技术帖
顺带帮大家免费代下载IT教程吧的资源 传送门

ThinkPHP 5.0 解决跨域

MR丶冷文 2021-04-16 134 0条评论 网站相关 ajax跨域tp5thinkphp

首页 / 正文

最近在做Freewind-Helper,就是给Feewind主题提供一些更多的功能扩展,也打算开发一些功能性API供大家调用,在开发过程中就突然想到大家可能很多时候是在前端发Ajax调API,显然,此时过来的请求是跨域请求,然后自已在网上查了些资料给大家分享一下

https://imagebed-1252410096.cos.ap-nanjing.myqcloud.com/20210415/e23638bd4d0747049c06bdcc46f9cd96.png

跨域

首先,大家要知道跨域是怎么产生的?

同源策略

跨域是因为浏览器的同源策略(浏览器上为安全性考虑实施的非常重要的安全策略)所导致

何为同源?我们来看看一个URL的组成协议:\\域名\路径:端口?参数名=参数值&参数名=参数值&...

其中当协议、域名、端口都相同时才算同源

  • 比如https://www.kevinlu98.cnhttp://www.kevinlu98.cn这两个URL,它两协议不同,所以不同源
  • 比如https://www.kevinlu98.cn:80https://www.kevinlu98.cn:8080这两个URL,它两的端口不同,很明显不同源
  • 比如https://www.kevinlu98.cn/aaa/bbb/ccc?name=lengwen&age=22https://www.kevinlu98.cn这两个URL,它两只有路径与参数不一样,所以同源

而浏览器的同源策略并不非是限制了发起跨域请求,而是在发起跨域请示时增加一次HTTP请求,称之为预检请求,此次请示使用OPTIONS方法发送到服务器,以获知服务器是否允许该实际请求

解决方案

跨域的解决有不少,大家也可以看出我在谈跨域产生的时候一直在说浏览器的同源策略,也就是说跨域请求只会在浏览器中产生

拿这点来看的话我们似乎有了点解决思路

  • 可以用像NGINX 这样的服务器去做反向代理
  • 对于webpack这种项目其本身就是运行于nodejs的,而nodejs本身就不是浏览器,所以可以直接用nodejs做一层代理
  • 还有其它好多,只要这个跨域请示不是由浏览器发出的,都可以从根本解决跨域问题
  • ......

这样是可以解决,但是很明显不可以解决我提出来的问题,我是想给大家去提供API接口让大家去调用,然后总不可能让调用者去解决跨域问题吧

别忘了上面还提到过浏览器不限制跨域请求的发送,所以我们可以在服务端程序里去配合浏览器事先发起的预检请求来完成跨域,在服务端接收到请示时判断是否为OPTIONS方法,如果是的话返回成功状态码表明允许发起跨域请示,然后在正式请示时在responseheader中加上允许跨域的信息来防止被浏览器拦截返回

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
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用行为扩展定义文件
return [
    // 应用初始化
    'app_init' => [],
    // 应用开始
    'app_begin' => [
        'app\\common\\behavior\\CronRun'
    ],
    // 模块初始化
    'module_init' => [],
    // 操作开始执行
    'action_begin' => [],
    // 视图内容过滤
    'view_filter' => [],
    // 日志写入
    'log_write' => [],
    // 应用结束
    'app_end' => [
        'app\\common\\behavior\\CronRun'
    ],
];

跨域请示发送成功

https://imagebed-1252410096.cos.ap-nanjing.myqcloud.com/20210415/ea787a9c3be84d468ec1f17e91288f1f.png

评论(0)

当前没有评论,还不快来留下第一个脚印吧

热门文章

最新评论

  • 难说博客

    那就回复看看

  • 他听

    给大佬递杯卡布奇诺[捂嘴笑]

  • 我愿提笔画尽天下

    向大佬低头[太开心]

  • flvck

    @MR丶冷文 [[呲牙]]可能看错了,不是这个

  • MR丶冷文

    @flvck ?? 这个主题应该还没发布呢[委屈]

日历

2021年05月

      1
2345678
9101112131415
16171819202122
23242526272829
3031     

文章目录

推荐关键字: IO模型 缓冲区 buffer java nio

上一张 下一张