本地使用,一切正常;後端專案和前端專案都部署到伺服器,一切正常;後端專案部署到伺服器,並設定允許跨網域存取後,本地前端專案使用伺服器上後端項目接口時,問題來了:
首先,使用postman測試獲取圖片驗證碼接口和驗證圖片驗證碼接口,正常。
然後,在html中使用獲取圖片驗證碼接口,正常;最後,在JS中使用驗證圖片驗證碼接口,出錯! ! !
分析
透過問題描述,我們看出,問題出現在跨域上。那麼,有兩種可能,一種是因為跨域設定不正確;一種是因為thinkphp本身的問題。
採用另外一種跨域配置,問題依然存在。那就是thinkphp本身的問題了,經過查找資料,問題定位在thinkphp的session跨域上。
跨子網域解決方法
其實不管是ThinkPHP還是php本身,在解決session跨域問題的時候都需要設定session.cookie_domain。
針對session跨域這一問題的解決方法主要有以下幾種:
第一種情況:如果目錄下沒有.htaccess這個文件,也就是沒有採取url偽靜態的話,那麼,在conf/config.php的第一行加上:
ini_set('session.cookie_domain',".domain.com");//跨域访问Session
這時如果你開啟了調試,那麼可以用!但關閉了調試,就不管用了!
第二種情況:如果你目錄下有.htaccess這個文件,那麼你在根目錄,index.php的第一行加入:
這個方法不管開不開啟調試都管用!
然而,我們的問題並不是跨子域的問題,而是完全跨域,所以上述方法無效。
完全跨域解決方案
取得圖片驗證碼請求
查看獲取圖片驗證碼的請求信息,Request Headers為:
Accept:image/webp,image/*,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4 Connection:keep-alive Cookie:pma_lang=zh_CN; pma_collation_connection=utf8_unicode_ci; pma_iv-1=wnpO4gv0eQRW1AMHmGr2ww%3D%3D; pmaUser-1=weZPqS0%2BW7nzFUVHRdqcfA%3D%3D Host:api.voidking.com Referer:http://localhost/ajax/ajax.html User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Response Headers為:
Access-Control-Allow-Origin:* Cache-Control:post-check=0, pre-check=0 Cache-Control:private, max-age=0, no-store, no-cache, must-revalidate Connection:keep-alive Content-Type:image/png Date:Sun, 27 Nov 2016 12:10:44 GMT Expires:Thu, 19 Nov 1981 08:52:00 GMT Pragma:no-cache Server:nginx Set-Cookie:PHPSESSID=721t4sqanvsii550m1dk8gq1o3; path=/; domain=.voidking.com Transfer-Encoding:chunked
驗證驗證碼請求
查看驗證碼的請求訊息,Request Headers為:
Accept:application/json, text/javascript, */*; q=0.01 Accept-Encoding:gzip, deflate Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4 Connection:keep-alive Content-Length:9 Content-Type:application/x-www-form-urlencoded; charset=UTF-8 Host:api.voidking.com Origin:http://localhost Referer:http://localhost/ajax/ajax.html User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Response Headers為:
Access-Control-Allow-Origin:* Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection:keep-alive Content-Encoding:gzip Content-Type:text/html; charset=UTF-8 Date:Sun, 27 Nov 2016 12:13:21 GMT Expires:Thu, 19 Nov 1981 08:52:00 GMT Pragma:no-cache Server:nginx Set-Cookie:PHPSESSID=149t0hhs2icqaaemvp39onkgp4; path=/; domain=.voidking.com Transfer-Encoding:chunked Vary:Accept-Encoding
再次取得圖片驗證碼請求
#Request Headers為:
Accept:image/webp,image/*,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4 Cache-Control:max-age=0 Connection:keep-alive Cookie:pma_lang=zh_CN; pma_collation_connection=utf8_unicode_ci; pma_iv-1=wnpO4gv0eQRW1AMHmGr2ww%3D%3D; pmaUser-1=weZPqS0%2BW7nzFUVHRdqcfA%3D%3D; PHPSESSID=721t4sqanvsii550m1dk8gq1o3 Host:api.voidking.com Referer:http://localhost/ajax/ajax.html User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Response Headers為:
Access-Control-Allow-Origin:* Cache-Control:private, max-age=0, no-store, no-cache, must-revalidate Cache-Control:post-check=0, pre-check=0 Connection:keep-alive Content-Type:image/png Date:Sun, 27 Nov 2016 13:26:21 GMT Expires:Thu, 19 Nov 1981 08:52:00 GMT Pragma:no-cache Server:nginx Transfer-Encoding:chunked
三次要求比較
第一次取得圖片驗證碼請求,Cookie中沒有PHPSESSID,所以,回傳訊息中有Set-Cookie。第二次取得圖片驗證碼請求,Cookie中含有PHPSESSID,所以,回傳訊息中沒有了Set-Cookie。
而且第一次要求回傳訊息Set-Cookie中的PHPSESSID,和第二次請求請求訊息Cookie中的PHPSESSID是相同的。
而驗證圖片驗證碼的ajax請求,沒有Cookie,自然也沒有PHPSESSID,所以,回傳訊息中也有Set-Cookie。
可見,我們需要在前端做一些修改,使之發送請求時帶著Cookie。
前端jquery設定
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>jquery</title> </head> <body> <p> <img src="/static/imghwm/default1.png" data-src="http://api.voidking.com/owner-bd/index.php/Home/CheckCode/getPicCode" class="lazy" alt=""> <input type="text" id="picCode"> <input type="button" id="send" value="验证"> </p> <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script> $(function(){ $('#send').click(function(){ //console.log(document.cookie); $.ajax({ url: 'http://api.voidking.com/owner-bd/index.php/Home/CheckCode/checkPicCode', type: 'POST', crossDomain: true, xhrFields: { withCredentials: true }, dataType: 'json', data: {code: $('#picCode').val()}, success: function(data){ console.log(data); }, error: function(xhr){ console.log(xhr); } }); }); }); </script> </body> </html>
請求報錯誤如下:
A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
出現了跨域報錯,可見後端也需要做一些修改,使之可以接收跨域Cookie。
後端nginx設定
add_header Access-Control-Allow-Origin http://localhost; add_header Access-Control-Allow-Credentials true;
注意:
伺服器端Access-Control-Allow-Credentials參數為true時,Access-Control-Allow-Origin參數的值不能為*。
後端nginx設定後,jquery的ajax請求正常了,可以攜帶Cookie,後端正常接收資料並回傳資料。
由於angular的ajax請求不同於jquery,所以,我們還需要研究一下angular怎麼發送攜帶Cookie的跨域請求。
前端angular設定
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>angular</title> <script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script> </head> <body ng-app="myApp" > <p ng-controller="myCtrl"> <img src="/static/imghwm/default1.png" data-src="http://api.voidking.com/owner-bd/index.php/Home/CheckCode/getPicCode" class="lazy" alt=""> <input type="text" id="picCode" ng-model="picCode"> <input type="button" ng-click="send()" value="验证"> </p> <script> var app = angular.module('myApp', []); app.controller('myCtrl', function($scope, $http, $httpParamSerializer) { $scope.send = function(){ $http({ method:'POST', url:'http://api.voidking.com/owner-bd/index.php/Home/CheckCode/checkPicCode', headers:{ 'Content-Type':'application/x-www-form-urlencoded' }, withCredentials: true, dataType: 'json', data: $httpParamSerializer({code: $scope.picCode}) }).then(function successCallback(response) { console.log(response.data); $scope.username = response.data.username; }, function errorCallback(response) { console.log(response.data); }); } }); </script> </body> </html>
推薦教學:《TP5》
以上是thinkphp中session跨域問題解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Linux新版
SublimeText3 Linux最新版

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver CS6
視覺化網頁開發工具