老生常談的跨域問題JSONP解決方式

原由

提及來源...今天去茶水間倒水時,偶然聽到公司面試官在問面試者前端跨域的如何解決。我心中默默想了一想,啪啪啪瞬間想出幾個關鍵詞,iframe,cors,同源策略,jsonp...轉念一想,雖然這是很常見的面試題,然而我在開發過程當中,還真沒有用過jsonp這種方式...就連原理也說很差。一陣冷汗,? ,趕忙去找了相關資料。javascript

同源策略

對於同源策略,在這裏我就很少累贅敘述了,簡單來講,若是如下三項:同一協議同一域名同一端口但凡是有一項不知足,瀏覽器就會把 No 'Access-Control-Allow-Origin' header is present on the requested resource甩你一臉。前端

解決方案

跨域問題能夠說在前端方面不可避免,但同源策略畢竟在保護網絡信息安全方面起到很大的做用。試想若是沒有同源策略,別的網頁能夠輕鬆竊取你的cookie,而假如你的cookie中存有你的我的信息...太可怕了,不過話說回來同源策略帶來的跨域問題也很頭疼,幸虧如今已經有多種方式可以解決。java

  1. CORS 跨域資源共享策略(web

  2. JSONP面試

  3. window.nameajax

  4. document.domain(主域相同的狀況下可用)json

  5. postMessage(h5新引入)跨域

  6. websocket(h5新引入,不受同源策略限制,因此說h5真是個好東西...?)瀏覽器

  7. ...安全

因爲篇幅有限(好吧...實際上是我寫不了那麼多),在這裏對於其餘解決方式就不一一詳解了。

正主來了,JSONP

JSONPJSON with Padding的簡稱,是一種較爲經常使用的解決跨域訪問的方式。咱們先來看一段示例代碼:

ajax({//此ajax方法是封裝了XMLHttpRequest對象實現,具體代碼與本文無關就不貼了
  method : 'get',
  url : 'http://127.0.0.1:8787',
  data : {
  'name' : '小明',//此ajax方法會自動將數據以get方式提交
  'age' : 22
  },
  success : function (message) {
    alert(message);
  },
  async : true
})

上面的代碼很簡單,瀏覽器端發起了一個異步ajax請求,讓咱們來看看服務端代碼:

app.get('*', function(req, res) {//這裏只截取了關鍵代碼
  res.send("測試數據");
});

清晰,易懂~so,what happend?

跨域報錯

不出所料,瀏覽器甩了我一臉...
易地再戰!JSONP炸裂出場~

function showJsonp(obj){
  console.log(obj.message);
}
var url = 'http://127.0.0.1:8787/?func=showJsonp'
var script = document.createElement('script');
script.setAttribute('src',url);
script.setAttribute('type','text/javascript');
document.getElementsByTagName('head')[0].appendChild(script);

再來後臺代碼~

app.get('*', function(req, res) {
  let callback = req.query.func;
  let content = callback+"({'message':'測試數據2'})";
  res.send(content);
});

結果:

jsonp解決跨域

大!獲!全!勝!
是時候分析一波戰術策略了~在日常寫代碼的時候,可能不少人沒有注意,瀏覽器對於script,iframe等標籤的src等屬性,是沒有同源策略限制的。而jsonp就很好的利用了這一點~在咱們發起請求時,url後跟了一個名爲func的參數,而這個參數就是以後須要用到的回調函數名稱。
咱們經過動態插入script標籤的方式,利用script標籤的src屬性發起請求,瀏覽器不會以同源策略來找事...然後臺根據請求構造出的數據長啥樣呢?

showJsonp({'message':'測試數據2'})

告訴我!這段代碼插入你的script標籤內後,會發生啥?!
固然是執行早就定義好的showJsonp函數啊~
bingo,完美解決跨域問題~~

最後

jsonp的方式兼容性很是好,即使是那些老古董瀏覽器,也能夠用jsonp的方式解決跨域問題,可是它也有所限制,它只能使用get方式發起請求,而且對於不一樣域之間頁面的js互相調用無能爲力。

相關文章
相關標籤/搜索