關於瀏覽器跨域問題Access-Control-Allow-Origin

其實很早就接觸過前端開發 也處理過跨域問題(當時採用的是jsonp server+client 都要改動。。。。)
javascript

如今這段時間也在作這塊 記錄+整理php

跨域問題是什麼gui?

一個網站的網址組成包括協議名,域名,端口號。好比 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爲指定可獲取數據的域名

jsonp的解決方式(僅支持GET方式)

json≠jsonp

原理

jsonp解決跨域問題的原理是,瀏覽器的script標籤是不受同源策略限制(你能夠在你的網頁中設置scriptsrc屬性問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                 + ');';
}


服務端設置Access-Control-Allow-Origin(CORS

這種方式只要服務端把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插件也可)

CORS

服務端代理經過在同域名下的web服務器端建立一個代理,這個須要在服務器端作 服務器的負荷+++

nginx反向代理

<script> 跨域獲取資源(要求返回的是正規的js對象格式 如json、js數組)

隱藏iframe、共享domain只適用在具備同一個父域下的跨域請求上

相關文章
相關標籤/搜索