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. 自己準備中間件

    創建中間件:

    <?php
    /**
     * 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了)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章