zoukankan      html  css  js  c++  java
  • lumen使用CORS解决跨域问题

    因为公司的业务是前后端分离,web前端和后端接口域名不同,所以存在跨域问题,开始使用的是jsonp解决,但是因为接口风格是rest的,还有delete、put等请求,jsonp就不够用了(涉及HTTP简单请求和复杂请求,这里有详细介绍),因此就找到了CORS跨域解决方案。原理过长,所以本篇文章只写服务端代码实现部分。

    代码实现

    app/Http/Middleware 里新建一个CorsMiddleware.php,并写入如下代码:

    
    <?php
    /*
     * Author:xx_lufei
     * Time:2016年11月3日13:15:51
     * Note:Access Control Headers.
     */
    
    namespace AppHttpMiddleware;
    
    
    use IlluminateHttpRequest;
    use IlluminateHttpResponse;
    
    class CorsMiddleware
    {
        private $headers;
        private $allow_origin;
    
        public function handle(Request $request, Closure $next)
        {
            $this->headers = [
                'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE',
                'Access-Control-Allow-Headers' => $request->header('Access-Control-Request-Headers'),
                'Access-Control-Allow-Credentials' => 'true',//允许客户端发送cookie
                'Access-Control-Max-Age' => 1728000 //该字段可选,用来指定本次预检请求的有效期,在此期间,不用发出另一条预检请求。
            ];
    
            $this->allow_origin = [
                'http://localhost',
                'http://192.168.1.12:8080'
            ];
            $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
    
            //如果origin不在允许列表内,直接返回403
            if (!in_array($origin, $this->allow_origin) && !empty($origin))
                return new Response('Forbidden', 403);
            //如果是复杂请求,先返回一个200,并allow该origin
            if ($request->isMethod('options'))
                return $this->setCorsHeaders(new Response('OK', 200), $origin);
            //如果是简单请求或者非跨域请求,则照常设置header
            $response = $next($request);
            $methodVariable = array($response, 'header');
            //这个判断是因为在开启session全局中间件之后,频繁的报header方法不存在,所以加上这个判断,存在header方法时才进行header的设置
            if (is_callable($methodVariable, false, $callable_name)) {
                return $this->setCorsHeaders($response, $origin);
            }
            return $response;
        }
    
        /**
         * @param $response
         * @return mixed
         */
        public function setCorsHeaders($response, $origin)
        {
            foreach ($this->headers as $key => $value) {
                $response->header($key, $value);
            }
            if (in_array($origin, $this->allow_origin)) {
                $response->header('Access-Control-Allow-Origin', $origin);
            } else {
                $response->header('Access-Control-Allow-Origin', '');
            }
            return $response;
        }
    }
    
    

    通过数组的形式实现允许多个origin。

    boostrap/app.php 里注册一下全局中间件即可完成

    
    $app->middleware([
     AppHttpMiddlewareCorsMiddleware::class,
    ]);
    
    

    注意

    默认情况下,cookie是不包括在CORS请求中的,如果服务器要接受cookie,必须设置

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

    如果不需要cookie,则必须删除该字段,改false是没用的,这个值只能是true。

    如果是更复杂的业务需求,可以把method提出来做相应的逻辑判断。

    与JSONP的比较

    CORS与JSONP的使用目的相同,但是比JSONP更强大。
    JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

    原文地址:https://www.jianshu.com/p/ce6a14a4a270
  • 相关阅读:
    Codeforces Round #605 (Div. 3)E
    Codeforces Round #628 (Div. 2)
    Codeforces Round #627 (Div. 3)
    AC自动机,知识点+hdu模板题
    Tire树,hdu2846,hdu4825
    Educational Codeforces Round 83 (Rated for Div. 2)
    分层最短路
    初入mysql的学习
    赛后总结
    Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) D
  • 原文地址:https://www.cnblogs.com/lovellll/p/10409475.html
Copyright © 2011-2022 走看看