面試題-探索JSONP

有這樣一個面試題: 什麼是jsonp,jsonp爲何沒有post。那麼,咱們先看看什麼是jsonp,瞭解了在看這個問題。javascript

什麼是JSONP


JSONP是JSON with Padding的略稱。它是一個非官方的協議,它容許在服務器集成JavaScript返回至 客戶端,經過javascript callback形式實現跨域訪問。html

爲何會有跨域這個說法呢?


由於同源策略!瀏覽器安全是來自於同源策略。什麼是同源策略呢?咱們知道在網絡中安全很是重要,否則你的密碼,帳號,重要數據都會被別人竊取,別人能夠在網上獲取到這些數據,模仿成你,騙過瀏覽器,隨心所欲,這樣的狀況是不容許發生的。因而就有了同源策略一說。 規定以下:前端

協議相同
域名相同
端口相同
複製代碼

知足以上要求的網頁稱爲同源下的網頁。java

例如:
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不一樣源(域名不一樣)
http://v2.www.example.com/dir/other.html:不一樣源(域名不一樣)
http://www.example.com:81/dir/other.html:不一樣源(端口不一樣
複製代碼

不一樣源的網頁共有三種行爲會受到限制:面試

1. Cookie、LocalStorage、IndexDB沒法讀取。
2. DOM沒法得到。
3. AJAX請求不能發送。
複製代碼

這樣一來,就很安全了!那麼這麼作有好處,爲何還須要跨域呢?由於不方便,由於同源策略一棒子打死了一片,有人用着不舒服,因而就有了jsonp跨域。說的這麼高大上,能夠說就是一個script小技巧。數據庫

說了這麼鋪墊知識,下面開始一段Long story簡潔版 jsonp (多圖預警!!!)json

Long Story


小Po今天要作一個付錢的頁面,頁面顯示帳戶餘額,還要有一個付款的按鈕。蹬蹬蹬。。搞定了:後端

而後他須要一個數據庫,否則用戶刷新一下,蹬蹬蹬。。又搞定了!

接下來給按鈕加一個事件,加哪個?個人DOM事件流有講事件處理程序喲!,因而小Po愉快的加上了DOM2級事件處理程序,接下來向後端發一個請求吧!跨域

  • 那就用form表單提交一個post這樣沒問題吧?蹬蹬蹬。。。。

成功的完成了,但是有個問題我必須的刷新一下才會顯示,這樣是否是體驗很不暢。

那麼還有什麼能夠發送請求的,a標籤?不行,那個須要點擊一下呢?並且a標籤看起來很奇怪不是嗎?那img標籤怎麼樣?好像可行哦,試試,蹬蹬蹬。。。瀏覽器

  • 那就試試<img>來發送請求吧

不錯,不錯,我在 <img>標籤裏面加了自動刷新,這樣彈窗出來後不就能夠自動刷新了嗎?並且還有一個狗狗圖片傳過來,多有意思!簡直太棒!

因而A同志高興的提交了代碼,沒過多久,就被打回來了,你這個請求還不錯,怎麼總是給傳個狗子過來,勞資不要狗,我要錢!你懂嗎?錢!

因而,爲了這個低俗的需求,小Po又得從新找,這回找到了<script>,這回別處岔子了。蹬蹬蹬。。。

  • 最後嘗試下<script>,ORZ

因而小Po將img換成script,打出一個彈窗,嗯,有兩個彈窗,一個是HTML的,一個是服務器中的,看會發生什麼。

而後付款,怎麼沒扣錢???

虛驚一場~~~原來是沒添加進body!!爲啥?不爲啥!記住吧。

居然能在服務器端可使用js,小Po彷彿發現了新大陸!,因而悄悄的在服務器返回的JS中操做了HTML,這樣就能扣錢而不用刷新頁面,一箭雙鵰,一石二鳥,一舉兩得。。。。完美!!!!

因而小Po自信的提交了代碼,然而,並板凳還沒坐熱,意見又來了。

「小Po啊,你醬紫我後端很難作啊(點根菸),你看看,我還要知道你頁面寫的是啥,我才能寫響應,這樣我均可以作前端,要你何用?!(彈了菸頭,踩滅)你在好好想一想吧!還有哦,你這個<script>付一次錢就在頁面添加一個script標籤,真的麻煩。這麼爛的代碼,是要我帶20米的砍刀麼?(吐出煙霧,一臉gaygay)」。

小Po心驚膽顫的撿起鍵盤,顫巍巍的刪除了response裏面的代碼,懷疑人生。算了,先ka掉重複script!再想解決辦法。

搞定!小Po重拾信心,還有什麼辦法解決代碼太過於耦合呢?既然我不能放在後端,那我放在頁面裏面怎麼樣,但是這個代碼怎麼執行呢?誒?放函數裏面,讓後端段響應的同時執行我頁面的函數不就OK啦。

「喂,解決沒?」

「大哥這樣怎麼樣?」

「不行!代碼仍是太多了,爺沒時間寫你那個什麼函數名字,你等會,我去找個人刀」

「(T T)ORZ」

  • 抓緊時間,再看看問題怎麼解決

我帶個參數過去,讓後端可以截取函數名,響應的時候調用這個函數名對應的函數就行了,這樣就不會讓他知道我要執行什麼代碼。耦合不就降下來了嗎?簡直是一舉。。。 =。= 先提交看看吧。

「來!頭伸過來。。

已經提交上去了。」

「是嗎?給你一次機會,嗯?!數據怎麼傳過去呢?」

「用json什麼放在‘我要傳輸的數據’ 的那個位置就行了。」

「嗯。。。還行,過得去,今天就不砍你啦。給你個紅包領着你的狗子回家吧。

「收工!」

jsonp爲何沒有post


由於是動態建立script標籤呀,script不能發post請求呀。完!

相關文章
相關標籤/搜索