同源策略(Same origin policy),它是由Netscape提出的一個著名的安全策略。如今全部支持JavaScript的瀏覽器都會使用這個策略。所謂同源是指,域名,協議,端口相同。[2] 同源策略限制從一個源加載的文檔或腳本如何與來自另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的關鍵的安全機制。[3]javascript
若是非同源,共有三種行爲受到限制:html
Asynchronous JavaScript and XML (Ajax) Ajax 容許在不干擾 Web 應用程序的顯示和行爲的狀況下在後臺進行數據檢索。使用 XMLHttpRequest 函數獲取數據,它是一種 API,容許客戶端 JavaScript 經過 HTTP 鏈接到遠程服務器。
對於AJAX以何種格式來交換數據、跨域需求如何解決。一種方案是:用JSON來傳數據,靠JSONP來跨域。前端
是JSON with Padding的略稱。它是一個非官方的跨域數據交互協議協議,它容許在服務器端集成Script tags返回至客戶端,經過javascript callback的形式實現跨域訪問(這僅僅是JSONP簡單的實現形式)。[4]java
通俗的闡釋:jquery
1.Ajax直接請求普通文件存在跨域無權限訪問的問題,不管是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一概不許;nginx
2.Web頁面上調用js文件時則不受是否跨域的影響(凡是擁有"src"這個屬性的標籤都擁有跨域的能力,好比<script>、<img>、<iframe>);web
3.基於上述,若是想經過純web端(ActiveX控件、服務端代理、HTML5之Websocket等方式暫不考慮)跨域訪問數據存在這樣一種可能:即在遠程服務器上設法把數據裝進js格式的文件裏,供客戶端調用和進一步處理;ajax
4.恰巧,JSON做爲純字符數據格式能夠簡潔的描述複雜數據,更妙的是JSON還被js原生支持,因此在客戶端幾乎能夠爲所欲爲的處理這種格式的數據;json
5.因而,解決方案:web客戶端經過與調用腳本如出一轍的方式,來調用跨域服務器上動態生成的js格式文件(通常以JSON爲後綴),顯而易見,服務器之因此要動態生成JSON文件,目的就在於把客戶端須要的數據裝入進去。api
6.客戶端在對JSON文件調用成功以後,也就得到了本身所需的數據,剩下的就是按照本身需求進行處理和展示了,這種獲取遠程數據的方式看起來很是像AJAX,但其實並不同。
7.爲了便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP,該協議的一個要點就是容許用戶傳遞一個callback參數給服務端,而後服務端返回數據時會將這個callback參數做爲函數名來包裹住JSON數據,這樣客戶端就能夠隨意定製本身的函數來自動處理返回數據了。[6]
JSONP是服務器與客戶端跨源通訊的經常使用方法。最大特色就是簡單適用,老式瀏覽器所有支持,服務器改造很是小。
在「跨域」的問題上,咱們發現src 屬性並無受到相關的限制,好比 img / script 等。
JSONP的基本思想是,網頁經過添加一個<script>標籤,設置這個script標籤的src屬性用於向服務器請求JSON數據 ,src屬性的查詢字符串必定要加一個callback函數,用來指定回調函數的名字 。而這個函數是在資源加載以前就已經在前端定義好的,這個函數接受一個參數並利用這個參數作一些事情。向服務器請求後,服務器會將JSON數據放在一個指定名字的回調函數裏做爲其參數傳回來。這時,由於函數已經在前端定義好了,因此會直接調用。
首先,網頁動態插入<script>元素,由它向跨源網址發出請求。
function addScriptTag(src) { var script = document.createElement('script'); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script); } window.onload = function () { addScriptTag('http://example.com/ip?callback=foo');//請求服務器數據並規定回調函數爲foo } function foo(data) { console.log('Your public IP address is: ' + data.ip); };
上面代碼經過動態添加<script>
元素,向服務器example.com
發出請求。注意,該請求的查詢字符串有一個callback
參數,用來指定回調函數的名字,這對於JSONP是必需的。
服務器收到這個請求之後,會將數據放在回調函數的參數位置返回。
foo({ "ip": "8.8.8.8" });
因爲<script>
元素請求的腳本,直接做爲代碼運行。這時,只要瀏覽器定義了foo函數,該函數就會當即調用。做爲參數的JSON數據被視爲JavaScript對象,而不是字符串,所以避免了使用JSON.parse
的步驟。[1]
jQuery 擁有對 JSONP 回調的本地支持。若是指定了 JSONP 回調,就能夠加載位於另外一個域的 JSON 數據,回調的語法爲:url?callback=?。
jQuery 自動將 ? 替換爲要調用的生成函數名。清單 4 顯示了該代碼。
清單 4. 使用 JSONP 回調
jQuery.getJSON(url+"&callback=?", function(data) { alert("Symbol: " + data.symbol + ", Price: " + data.price); });
爲此,jQuery 將一個全局函數附加到插入腳本時須要調用的窗口對象。另外,jQuery 也能優化非跨域調用。若是向同一個域發出請求,jQuery 就將其轉化爲普通 Ajax 請求。[5]
jQuery框架也固然支持JSONP,可使用$.getJSON(url,[data],[callback])方法。
http://api.jquery.com/jQuery....
要注意的是在url的後面必須添加一個callback參數,這樣getJSON方法纔會知道是用JSONP方式去訪問服務,callback後面的那個問號是內部自動生成的一個回調函數名。
在上一個例子中,使用了靜態文件(ticker.js)將 JavaScript 動態插入到 Web 頁面中。儘管返回了 JSONP 回覆,但它不容許您在 URL 中定義回調函數名。這不是 JSONP 服務。所以,如何才能將其轉換爲真正的 JSONP 服務呢?可以使用的方法不少。這裏咱們將分別使用 PHP 和 Java 展現兩個示例。
首先,假設您的服務在所請求的 URL 中接受了一個名爲 callback 的參數。(參數名不重要,可是客戶和服務器必須都贊成該名稱)。另外假設向服務發送的請求是這樣的:
http://www.yourdomain.com/jsonp/ticker?symbol=IBM&callback=showPrice
在這種狀況下,symbol 是表示請求 ticker symbol 的請求參數,而 callback 是 Web 應用程序的回調函數的名稱。使用清單 5 所示的代碼能夠經過 jQuery 的 JSONP 支持調用該服務。
清單 5. 調用回調服務
jQuery.getJSON("http://www.yourdomain.com/jsonp/ticker?symbol=IBM&callback=?", function(data) { alert("Symbol: " + data.symbol + ", Price: " + data.price); });
注意,咱們使用 ? 做爲回調函數名,而非真實的函數名。由於 jQuery 會用生成的函數名替換 ?。因此您不用定義相似於 showPrice() 的函數。
Digg API:來自 Digg 的頭條新聞:
http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript &callback=?
Geonames API:郵編的位置信息:
http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
Flickr API:來自 Flickr 的最新貓圖片:
http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any &format=json&jsoncallback=?
http://api.jquery.com/jQuery....
(Cross-Origin Resource Sharing )
跨來源資源共享(CORS)是一份瀏覽器技術的規範,提供了 Web 服務從不一樣網域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是 JSONP 模式的現代版。與 JSONP 只能發GET要求不一樣,CORS 容許任何類型請求。用 CORS 可讓網頁設計師用通常的 XMLHttpRequest,這種方式的錯誤處理比 JSONP 要來的好。另外一方面,JSONP 能夠在不支持 CORS 的老舊瀏覽器上運做。現代的瀏覽器都支持 CORS。[4]
1.瀏覽器同源政策及其規避方法--阮一峯
2.baidu
3.MDN
4.wiki
5.結合 JSONP 和 jQuery 快速構建強大的 mashup
6.說說JSON和JSONP,也許你會豁然開朗,含jQuery用例
7.W3Cschool
1.Web開發中跨域的幾種解決方案
2.瀏覽器的同源策略MDN
3.瀏覽器的同源策略
4.用nginx的反向代理機制解決前端跨域問題