Laravel 5.4 解决跨域JS跨域问题

问题:

利用了laravel开的接口,然后活动部分是用H5做的,方便更新,没有使用客户端原生,但是用H5请求接口是报了跨域问题。

jquery.min.js:4 Access to XMLHttpRequest at 'http://**.**.**.**:8085/index.php/and/v2.0.0/partner/answer' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
send @ jquery.min.js:4
ajax @ jquery.min.js:4
(anonymous) @ index.html:205
dispatch @ jquery.min.js:3
r.handle @ jquery.min.js:3
jquery.min.js:4 POST http://**.**.**.**:8085/index.php/and/v2.0.0/partner/answer net::ERR_FAILED

解决方案

  1. 前端采用JsonP请求,或者利用框架请求

  2. PHP接口的方法里添加header

       header('Access-Control-Allow-Origin:*');
       // 响应类型
       header('Access-Control-Allow-Methods:*');
       //请求头
       header('Access-Control-Allow-Headers:*');
       // 响应头设置
       header('Access-Control-Allow-Credentials:false');//cookie 置为true
    
  3. NGINX代理设置

    
    server
    {
       listen 8084;
       server_name localhost;
       location /index.php/ {
           proxy_pass http://localhost:8085;
    
           #   指定允许跨域的方法,*代表所有
           add_header Access-Control-Allow-Methods *;
    
           #   预检命令的缓存,如果不缓存每次会发送两次请求
           add_header Access-Control-Max-Age 3600;
           #   带cookie请求需要加上这个字段,并设置为true
           add_header Access-Control-Allow-Credentials true;
    
           #   表示允许这个域跨域调用(客户端发送请求的域名和端口) 
           #   $http_origin动态获取请求客户端请求的域   不用*的原因是带cookie的请求不支持*号
           add_header Access-Control-Allow-Origin $http_origin;
    
           #   表示请求头的字段 动态获取
           add_header Access-Control-Allow-Headers 
           $http_access_control_request_headers;
    
           #   OPTIONS预检命令,预检命令通过时才发送请求
           #   检查请求的类型是不是预检命令
           if ($request_method = OPTIONS){
               return 200;
           }
       }
    }
    
  4. 利用laravel第三方包
    composer require barryvdh/laravel-cors

       位于:config/app.php,添加下面代码
       
       Barryvdh\Cors\ServiceProvider::class,
       全局使用:
       如果作为全局使用的中间件,则直接加入到 middleware 中即可:
       
       修改 app/Http/kernel.php 文件:
       
       protected $middleware = [
           // ...
           \Barryvdh\Cors\HandleCors::class,
       ];
       中间件组使用
       如果只是在中间件组中使用,则加入相应的中间件组就OK
       
       protected $middlewareGroups = [
           'web' => [
              // ...
           ],
       
           'api' => [
               // ...
               \Barryvdh\Cors\HandleCors::class,
           ],
       ];
       配置选项
       导出配置:
       
       php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"
       配置的基本内容:
       
       return [
            /*
            |--------------------------------------------------------------------------
            | Laravel CORS
            |--------------------------------------------------------------------------
            |
            | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
            | to accept any value.
            |
            */
           'supportsCredentials' => false,
           'allowedOrigins' => ['*'],
           'allowedHeaders' => ['Content-Type', 'X-Requested-With'],
           'allowedMethods' => ['*'], // ex: ['GET', 'POST', 'PUT',  'DELETE']
           'exposedHeaders' => [],
           'maxAge' => 0,
       ]
    
  5. 自己准备中间件

    创建中间件:

    
    /**
     * Created by PhpStorm.
     * User: machi
     * Date: 2018/5/24
     * Time: 下午2:39
     */
    namespace App\Http\Middleware;
    use Illuminate\Http\Request;
    use Closure;
    class Cors
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle(Request $request, Closure $next)
        {
            if(!empty($_SERVER["HTTP_ORIGIN"])){
                $allow_origin=$_SERVER["HTTP_ORIGIN"];
            }else{
                $allow_origin='http://test.senpuyun.com';
            }
            if(strtoupper($_SERVER['REQUEST_METHOD'])== 'OPTIONS'){
                return response('ok',200)
                    ->header('Access-Control-Allow-Origin', $allow_origin)
                    ->header('Access-Control-Allow-Credentials','true')
                    ->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
                    ->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS, DELETE,HEAD');
            }else{
                $response = $next($request);
                $response->header('Access-Control-Allow-Origin', $allow_origin);
                $response->header('Access-Control-Allow-Credentials','true');
                $response->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
                $response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS, DELETE,HEAD');
                return $response;
            }
        }
    }
    

    注册:
    bootstrap/app.php

    $app->routeMiddleware([
        'auth' => App\Http\Middleware\Authenticate::class,
        'jwtauth'    => App\Http\Middleware\JwtAuthenticate::class,
        'jwtrefresh'    => App\Http\Middleware\JwtRefreshToken::class,
        'partner' => App\Http\Middleware\Partner::class,
        'cors' =>\App\Http\Middleware\Cors::class,
        //'jwt.auth'    => Tymon\JWTAuth\Middleware\GetUserFromToken::class,
        //'jwt.refresh' => Tymon\JWTAuth\Middleware\RefreshToken::class,
    ]);
    

    路径配置:

    $app->group(['prefix' => 'and/{version}'], function () use($app){
        $app->group(['middleware' => 'cors'], function($api) {
            $api->group(['middleware' => 'partner'], function($api1) {
                $api1->post('partner/answer', ['as' => 'partner.answer', 'uses' => 'PartnerController@answer']);
            });
        });
     )};   
    

    本人用的最后一种方法。然后大家需要注意避免重复设置。重复设置可能会出现错误The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed , contains multiple values “*” 意思就是设置了2次跨域,但是只有一个是允许的,移除其中的任意一个就好了。如果服务器设置了允许跨域,使用Nginx代理里面就不需要了(或者就不用使用Nginx了)

你可能感兴趣的:(Nginx,PHP)