備註 1: 我自己測的結果, 用 ajax 連到其它網域要東西, 對方的 server 還是會收到請求, 並傳回 200, 只是 ajax 不會得到結果, 我猜應該是瀏覽器自己擋掉拿回來的結果。所以, 即使有 same origin policy, 還是有可能讓使用者狂連其它網站, 浪費別人的資源。但也會留下 referral log 就是了。《JavaScript 抓取跨網域外的資料》 清楚的說明避開 Same origin policy 的兩個作法
- 透過自己網站的 proxy script, 就沒有 same origin policy 的限制。也就是說, 自己先寫好一個 proxy script (用 PHP / CGI, 什麼都可以), 要取用其它網域的檔案時, 先連到自家的 proxy script, 透過它連向目標 URL, 再直接傳回收到的結果。缺點是會增加 latency, 還有增加自家網站的負擔。
- html tag 沒有跨網域的限制 (不然連載入其它網站的圖和 CSS 都很麻煩), 可以用 <script type="text/javascript" src="http://OTHER-DOMAIN/some.js"></script> 載入執行另一個網域的 javascript。
由於 HTML 可以動態加入元件, 這讓使用 script tag 的作法有更多彈性, 可以動態載入其它 domain 的 javascript, 執行裡面的內容, 也方便控制執行的順序。若對方的 javascript 知道自己目前的內容 (DOM、javascript), 就可以搭起兩個網域的資料。於是有了 JSONP 的想法: OTHER-DOMAIN 提供一個 URL, 這個 URL 接受一個參數 callback, 表示 OUR-DOMAIN 寫好的函式名稱。OTHER-DOMAIN 則傳回 CALLBACK({...}) 的程式碼, 用 script tag 載入後會自動執行, 結果就是用 OUR-DOMAIN 的 CALLBACK 接受 OTHER-DOMAIN 「傳回」的 JSON 物件 ( 即 {...} ), 達到跨網域的需求。必要時 OTHER-DOMAIN 也可以多產生一些程式碼, 做些 CALLBACK 的前處理和後處理。
Wikipedia 有詳細的 JSONP 例子, 另外這裡和這裡也有不錯的例子, 觀察 server side (即 OTHER-DOMAIN) 和 client side (即 OUR-DOMAIN) 的原始碼和中間產生的 code, 就能明白它運作的機制。
使用 JSONP 的代價就是, 使用者得相信提供 JSONP API 的網站不會亂搞, 偷產生惡意程式碼, 這有點像接受外部的輸入, 再執行 eval 一樣, 方便歸方便, 卻有一定的風險。另外 jQuery 有提供 JSONP 的執行方式, 可以省掉自己產生 script tag 執行, 再砍掉它的步驟。
好像不是「style tag」,而是「script tag」。
回覆刪除已更正, 謝啦
回覆刪除