2017-05-03 19 views
3

我用laravel寫入後端。並嘗試從IONIC使用@angular/http調用api。API服務器始終響應「否」Access-Control-Allow-Origin'「

在後臺服務器中,我已經在中間件和響應中添加了Access-Control-Allow-Origin

中間件。

return $next($request) 
     ->header('Access-Control-Allow-Origin', '*') 
     ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE') 
     ->header('Access-Control-Allow-Credentials', true) 
     ->header('Access-Control-Allow-Headers', 'Content-Type') 
     ->header('Vary', 'Origin'); 

迴應。

return response($data, 200) 
     ->withHeaders([ 
     'Content-Type' => 'application/json', 
     'Access-Control-Allow-Origin' => '*', 
     'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE', 
     'Access-Control-Allow-Credentials' => true, 
     'Access-Control-Allow-Headers' => 'Content-Type', 
     'Vary' => 'Origin', 
     ]); 

離子

url: any = 'http://myurl.local/api/'; 

    headers = new Headers(
    { 
    'Accept' : 'application/json', 
    'Content-Type' : 'application/json', 
    'Access-Control-Request-Methods' : 'POST' 
    }); 
    options = new RequestOptions({ headers: this.headers }); 

login(username, password) { 
    let data = JSON.stringify({ 
     username : username, 
     password : password 
    }); 
    let fullUrl = this.url+'login'; 

    return new Promise((resolve, reject) => { 
     this.http.post(fullUrl, data, this.options) 
     .toPromise() 
     .then((response) => 
     { 
     console.log('API Response : ', response); 
     resolve(response.json()); 
     }) 
     .catch((error) => 
     { 
     console.error('API Error : ', error.toString()); 
     reject(error.json()); 
     }); 
    }); 
    } 

當我打電話API與'Content-Type' : 'application/json'它總是響應誤差。

XMLHttpRequest無法加載http://myurl.local/api/login。對 預檢請求的響應未通過訪問控制檢查:否 「所請求的 資源上存在」Access-Control-Allow-Origin「標頭。原因'http://localhost:8100'因此不允許 訪問。

但是,如果我將'Content-Type'更改爲'application/x-www-form-urlencoded'。我沒有得到任何錯誤。

但是,當我嘗試看輸入$request->all()。我得到的數據是'{"username":"XXXXXXXXXX","password":"XXXXXXXXXX"}' => NULL

與郵遞員很好。我真的嘗試了很多方法來解決這個問題,但是我做不到。

有什麼不對?

回答

4

Yeahhhh !!!最後,我可以解決這個問題。他媽的。

在中間件中。

public function handle($request, Closure $next) 
    { 
    if ($request->getMethod() == "OPTIONS") { 
     return response(['OK'], 200) 
     ->withHeaders([ 
      'Access-Control-Allow-Origin' => '*', 
      'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE', 
      'Access-Control-Allow-Credentials' => true, 
      'Access-Control-Allow-Headers' => 'Authorization, Content-Type', 
     ]); 
    } 

    return $next($request) 
    ->header('Access-Control-Allow-Origin', '*') 
    ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE') 
    ->header('Access-Control-Allow-Credentials', true) 
    ->header('Access-Control-Allow-Headers', 'Authorization, Content-Type'); 

    } 

在IONIC更改標題爲。

headers = new Headers(
{ 
    'Content-Type' : 'application/json' 
}); 

並且直到您添加options路線,它纔會起作用。 (在我的情況下,因爲我不使用Route::resource

Route::group(['middleware' => 'AddHeader'], function() 
{ 
    Route::post('/login', '[email protected]'); 
    Route::options('/login', '[email protected]'); 
}); 

PS。我在function index()有一些邏輯,我嘗試使用__construct()。但它不起作用。

1

在這種處理請求的Laravel代碼,你需要添加處理爲OPTIONS請求:

if ($request->getMethod() == "OPTIONS") { 
    $headers = [ 
     'Access-Control-Allow-Origin' => '*' 
     'Access-Control-Allow-Methods'=> 'POST, GET', 
     'Access-Control-Allow-Headers'=> 'Content-Type' 
    ]; 
    return Response::make('OK', 200, $headers); 
} 

當我打電話API與'Content-Type' : 'application/json'它總是響應誤差。

但是,如果我將'Content-Type'更改爲'application/x-www-form-urlencoded'。我沒有得到任何錯誤。

application/json content-type觸發瀏覽器執行CORS預檢OPTIONS請求。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests有更多細節。

隨着郵遞員很好。

郵差可以自由地做出不受限制的跨域請求。但瀏覽器不會允許您的前端JavaScript代碼訪問來自跨源請求的響應,除非響應表明請求發送的服務器正在選擇接收跨源請求。

如果您的請求觸發瀏覽器執行CORS預檢OPTIONS請求,請求發送到的服務器必須配置爲以正確的方式響應OPTIONS請求。這就是爲什麼您需要在您的Laravel代碼中爲OPTIONS請求添加額外的處理。

如果服務器沒有以正確的方式對OPTIONS預檢做出響應,那麼瀏覽器將停在那裏,並且永遠不會執行您實際嘗試發送的POST請求。

+0

在中間件或控制器? – ThunderBirdsX3

+0

在你的中間件代碼 – sideshowbarker

+0

可能是我做錯了什麼?它有同樣的問題。 ($ request-> getMethod()==「OPTIONS」){ $ headers = [ 'Access-Control-Allow-Methods'=>'公共函數句柄($ request,Closure $ next) POST,GET', 'Access-Control-Allow-Headers'=>'Content-Type' ]; 返回響應:: make('OK',200,$ headers); } return $ next($ request); }' – ThunderBirdsX3