本地代碼連遠程測試服務器的跨域問題



目標: 在本地調試,打開localhost:3000的一個網頁,希望此網頁內能通過ajax訪問www.aaa.com的一個api,訪問此api還需要傳cookie進行權限驗證


過程: 
1. 首先明白這是個跨域請求
2. 查看jquery的ajax參數,發現有兩個是用的到的,crossDomain代表是否跨域,withCredentials代表是否傳cookie,於是寫出了下面的代碼
       <script type="text/javascript">
$(function(){
$.ajax("http://www.aaa.com/user/info/", {
type: "GET",
success: function(data, status, xhr) { 
alert(data.name);             
},
xhrFields: {
withCredentials: true
},
crossDomain: true
});
  });
</script>
3. 執行時報錯,說通配符*不能用在Access-Control-Allow-Origin裏,用在裏面就不讓訪問
has been blocked by CORS policy: A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true.
Origin 'http://127.0.0.1:3000' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
4.  找到了兩個官方的解釋,如下鏈接內,明白了cors是如何進行控制跨域訪問的,裏面並沒有說到通配符*不能用。
https://www.w3.org/TR/cors/#access-control-allow-origin-response-header
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

但是另一個鏈接提到了此限制:
http://netsecurity.51cto.com/art/201311/419179.htm
如果程序猿偷懶將Access-Control-Allow-Origin設置爲允許來自所有域的跨域請求。
那麼cors的安全機制幾乎就無效了。不過先別高興的太早。其實這裏在設計的時候有一個很好的限制。xmlhttprequest發送的請求需要使用“withCredentials”來帶上cookie,
如果一個目標域設置成了允許任意域的跨域請求,這個請求又帶着cookie的話,這個請求是不合法的。(就是如果需要實現帶cookie的跨域請求,需要明確的配置允許來源的域,
使用任意域的配置是不合法的)瀏覽器會屏蔽掉返回的結果。javascript就沒法獲取返回的數據了。這是cors模型最後一道防線。假如沒有這個限制的話,
那麼javascript就可以獲取返回數據中的csrf token,以及各種敏感數據。這個限制極大的降低了cors的風險


5.  估計是瀏覽器主動把通配符給禁用掉了,既然*號不能用,如何解決問題呢?
先明白一點,跨域限制是瀏覽器的策略。
跨域限制啥意思呢?你要想訪問自己的數據,當然可以。你要想訪問別人的數據,除非別人服務器允許你這麼做,否則瀏覽器禁止你訪問。
a. 從服務器端着手,允許指定的域名跨域訪問,代碼如下(node代碼,用到了express的cors庫):
//1 不設置origin
// app.use(cors()); // Access-Control-Allow-Origin 爲 * 




//2  設置origin,不設置credentials
/* var corsOptions = {
 origin: 'http://127.0.0.1:3000',
 optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};


app.use(cors(corsOptions)); */


//3  設置origin並設置credentials
var corsOptions = {
 origin: 'http://127.0.0.1:3000',
 credentials: true,
 optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};


app.use(cors(corsOptions)); 
b. 從瀏覽器端着手,把瀏覽器的跨域限制功能關掉。
經過不懈尋找,發現真的可以把跨域限制功能關掉。
I:在cmd裏執行下面幾句代碼,或者做成一個bat文件。主要就是關掉所有chrome,然後啓動帶參數的chrome,注意(--user-data-dir是新一點(30以後)版本的chrome必須的)
TASKKILL /F /IM chrome.exe
start chrome.exe --args --disable-web-security --user-data-dir
pause
II: 更改chrome快捷方式,把參數加在裏面,但啓動快捷方式前也得把chrome進程全部殺掉
具體鏈接參照:http://www.cnblogs.com/jinling/p/5336722.html

III:據說firefox有一個插件,可以開關firefox的跨域功能,這個留着以後研究吧




參考鏈接:
1. https://www.w3.org/TR/cors/#access-control-allow-origin-response-header
2. https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
3. http://stackoverflow.com/questions/17679399/does-disable-web-security-work-in-chrome-anymore(在這裏找到了--user-data-dir參數)
4. http://www.cnblogs.com/jinling/p/5336722.html(更改chrome快捷方式,把參數加在裏面)
5. http://www.cnblogs.com/Leo_wl/p/4361289.html(node簡單服務器,包含登錄驗證功能)
6. http://netsecurity.51cto.com/art/201311/419179.htm(跨域基本知識)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章