其實很早就接觸過前端開發 也處理過跨域問題(當時採用的是jsonp server+client 都要改動。。。。)
javascript
如今這段時間也在作這塊 記錄+整理php
一個網站的網址組成包括協議名,域名,端口號。好比 http://www.sagosoft.com,其中http是協議名,www.sagosoft.com是域名,端口號是80,當在在頁面中從一個url請求數據時,若是這個url的協議名、子域名、主域名、端口號任意一個有一個不一樣,就會產生跨域問題。
即便是在 http://localhost:8080/
頁面請求 http://127.0.0.1:8080/
也會有跨域問題html
常見的不一樣域間的頁面制約dom元素包括:前端
window.location 能夠設置,但不能讀取。其它的 location 屬性和方法被禁止訪問;
document.href 能夠設置,但不能讀取。其它的 document 屬性和方法被禁止訪問;
<iframe> 的 src 能夠設置,但不能讀取html5
ajax訪問無返回值??java
因爲安全緣由,跨域訪問是被各大瀏覽器所默認禁止的;可是瀏覽器並不由止在頁面中引用其餘域的JS文件,並能夠自由執行引入的JS文件中的function
jquery
解決跨域問題有如下tri種方式nginx
使用jsonpgit
服務端代理github
服務端設置Request Header
頭中Access-Control-Allow-Origin
爲指定可獲取數據的域名
json≠jsonp
jsonp解決跨域問題的原理是,瀏覽器的script
標籤是不受同源策略限制(你能夠在你的網頁中設置script
的src
屬性問cdn服務器中靜態文件的路徑)。那麼就可使用script標籤從服務器獲取數據,請求時添加一個參數爲callbakc=?,?號時你要執行的回調方法。
以jQuery2.1.3的ajax方法爲例
$.ajax({ url:"", dataType:"jsonp", data:{ params:"" } }).done(function(data){ //dosomething..})
僅僅是客戶端使用jsonp請求數據是不行的,由於jsonp的請求是放在script
標籤中的,和普通請求不一樣的地方在於,它請求到的是一段js代碼,若是服務端返回了json字符串,那麼瀏覽器就會報錯。因此jsonp返回數據須要服務端作一些處理。
上面說了jsonp的原理是利用script
標籤來解決跨域,可是script
標籤是用來獲取js代碼的,那麼咱們怎麼獲取到請求的數據呢。
這就須要服務端作一些判斷,當參數中帶有callback屬性時,返回的type要爲application/javascript
,把數據做爲callback的參數執行。下面是jsonp返回的數據的格式示例
/* typeof jQuery21307270454438403249_1428044213638 === 'function'*/ jQuery21307270454438403249_1428044213638({"code":1,"msg":"success","data":{"test":"test"}});
這是express4.12.3關於jsonp的實現代碼
if (typeof callback === 'string' && callback.length !== 0) { this.charset = 'utf-8'; this.set('X-Content-Type-Options', 'nosniff'); this.set('Content-Type', 'text/javascript'); // restrict callback charset // replace chars not allowed in JavaScript that are in JSON callback = callback.replace(/[^\[\]\w$.]/g, ''); body = body.replace(/\u2028/g, '\\u2028') .replace(/\u2029/g, '\\u2029'); // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse" // the typeof check is just to reduce client error noise body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');'; }
這種方式只要服務端把response的header頭中設置Access-Control-Allow-Origin
爲制定可請求當前域名下數據的域名便可。通常狀況下設爲便可。這樣客戶端就不須要使用jsonp來獲取數據。
可是我的是用這個方法的
CORS支持POST提交,而且實施起來嘿簡單,CORS原理:只須要向響應頭header中注入Access-Control-Allow-Origin,這樣瀏覽器檢測到header中的Access-Control-Allow-Origin,則就能夠跨域操做。
我用的是php,用法如:(*號也能夠指定特定的域名,只容許該域名訪問)
<?php header("Access-Control-Allow-Origin:*"); //...
若是是java,
response.setHeader("Access-Control-Allow-Origin", "*");
Access-Control-Allow-Origin是html5新增的一項標準,IE10如下是不支持的,因此若是產品面向的是PC端,就要使用服務端代理或jsonp。
見圖
====================================================================
主要解決方案 :
jsonp (jquery-jsonp插件也可)
服務端代理(經過在同域名下的web服務器端建立一個代理,這個須要在服務器端作 服務器的負荷+++)
nginx反向代理
<script> 跨域獲取資源(要求返回的是正規的js對象格式 如json、js數組)
隱藏iframe、共享domain(只適用在具備同一個父域下的跨域請求上)