日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
頭條面試官:一文徹底搞懂JSONP

 一個正常的請求: JSON

為企業(yè)提供成都網(wǎng)站設(shè)計、做網(wǎng)站、網(wǎng)站優(yōu)化、成都全網(wǎng)營銷推廣、競價托管、品牌運營等營銷獲客服務(wù)。成都創(chuàng)新互聯(lián)擁有網(wǎng)絡(luò)營銷運營團隊,以豐富的互聯(lián)網(wǎng)營銷經(jīng)驗助力企業(yè)精準獲客,真正落地解決中小企業(yè)營銷獲客難題,做到“讓獲客更簡單”。自創(chuàng)立至今,成功用技術(shù)實力解決了企業(yè)“網(wǎng)站建設(shè)、網(wǎng)絡(luò)品牌塑造、網(wǎng)絡(luò)營銷”三大難題,同時降低了營銷成本,提高了有效客戶轉(zhuǎn)化率,獲得了眾多企業(yè)客戶的高度認可!

正常發(fā)請求時,curl 示例:

 
 
 
 
  1. $ curl https://shanyue.tech/api/user?id=100
  2. {
  3.   "id": 100,
  4.   "name": "shanyue",
  5.   "wechat": "xxxxx",
  6.   "phone": "183xxxxxxxx"
  7. }

使用 fetch 發(fā)送請求,示例:

 
 
 
 
  1. const data = await fetch('https://shanyue.tech/api/user?id=100', {
  2.   headers: {
  3.     'content-type': 'application/json',
  4.   },
  5.   method: 'GET',
  6. }).then(res => res.json())

請求數(shù)據(jù)后,使用一個函數(shù)來處理數(shù)據(jù)

 
 
 
 
  1. handleData(data)

一個 JSONP 請求

JSONP,全稱 JSON with Padding,為了解決跨域的問題而出現(xiàn)。雖然它只能處理 GET 跨域,雖然現(xiàn)在基本上都使用 CORS 跨域,但仍然要知道它,畢竟面試會問。

curl 示例

 
 
 
 
  1. $ curl https://shanyue.tech/api/user?id=100&callback=padding
  2. padding({
  3.   "id": 100,
  4.   "name": "shanyue",
  5.   "wechat": "xxxxx",
  6.   "phone": "183xxxxxxxx"
  7. })

對于正常的請求有何不同一目了然: 多了一個 callback=padding, 并且響應(yīng)數(shù)據(jù)被 padding 包圍,這就是 JSONP

那請求數(shù)據(jù)后,如何處理數(shù)據(jù)呢?此時的 padding 就是處理數(shù)據(jù)的函數(shù)

 
 
 
 
  1. window.padding = handleData

這里實現(xiàn)一個 jsonp 函數(shù)

 
 
 
 
  1. function jsonp_simple ({ url, onData, params }) {
  2.   const script = document.createElement('script')
  3.   // 一、默認 callback 函數(shù)為 padding
  4.   script.src = `${url}?${stringify({ callback: 'padding', ...params })}`
  5.   // 二、使用 onData 作為 window.padding 函數(shù),接收數(shù)據(jù)
  6.   window['padding'] = onData
  7.   document.body.appendChild(script)
  8. }

此時會有一個問題: window.padding 函數(shù)會污染全局,如果有多個請求發(fā)送如何處理?

使 jsonp 的回調(diào)函數(shù)名作為一個隨機變量,代碼如下

 
 
 
 
  1. function jsonp ({ url, onData, params }) {
  2.   const script = document.createElement('script')
  3.   // 一、為了避免全局污染,使用一個隨機函數(shù)名
  4.   const cbFnName = `JSONP_PADDING_${Math.random().toString().slice(2)}`
  5.   // 二、默認 callback 函數(shù)為 cbFnName
  6.   script.src = `${url}?${stringify({ callback: cbFnName, ...params })}`
  7.   // 三、使用 onData 作為 cbFnName 回調(diào)函數(shù),接收數(shù)據(jù)
  8.   window[cbFnName] = onData;
  9.   document.body.appendChild(script)
  10. }
  11. // 發(fā)送 JSONP 請求
  12. jsonp({
  13.   url: 'http://localhost:10010',
  14.   params: { id: 10000 },
  15.   onData (data) {
  16.     console.log('Data:', data)
  17.   }
  18. })

代碼附錄

完整代碼可見山月博客的 github 倉庫: https://github.com/shfshanyue/blog/tree/master/code/jsonp/

JSONP 實現(xiàn)完整代碼:

 
 
 
 
  1. function stringify (data) {
  2.   const pairs = Object.entries(data)
  3.   const qs = pairs.map(([k, v]) => {
  4.     let noValue = false
  5.     if (v === null || v === undefined || typeof v === 'object') {
  6.       noValue = true
  7.     }
  8.     return `${encodeURIComponent(k)}=${noValue ? '' : encodeURIComponent(v)}`
  9.   }).join('&')
  10.   return qs
  11. }
  12. function jsonp ({ url, onData, params }) {
  13.   const script = document.createElement('script')
  14.   // 一、為了避免全局污染,使用一個隨機函數(shù)名
  15.   const cbFnName = `JSONP_PADDING_${Math.random().toString().slice(2)}`
  16.   // 二、默認 callback 函數(shù)為 cbFnName
  17.   script.src = `${url}?${stringify({ callback: cbFnName, ...params })}`
  18.   // 三、使用 onData 作為 cbFnName 回調(diào)函數(shù),接收數(shù)據(jù)
  19.   window[cbFnName] = onData;
  20.   document.body.appendChild(script)
  21. }

JSONP 服務(wù)端適配相關(guān)代碼:

 
 
 
 
  1. const http = require('http')
  2. const url = require('url')
  3. const qs = require('querystring')
  4. const server = http.createServer((req, res) => {
  5.   const { pathname, query } = url.parse(req.url)
  6.   const params = qs.parse(query)
  7.   const data = { name: 'shanyue', id: params.id }
  8.   if (params.callback) {
  9.     str = `${params.callback}(${JSON.stringify(data)})`
  10.     res.end(str)
  11.   } else {
  12.     res.end()
  13.   }
  14. })
  15. server.listen(10010, () => console.log('Done'))

JSONP 頁面調(diào)用相關(guān)代碼

 
 
 
 
  1.   
  2.   
  3.   
  4.   

JSONP 實現(xiàn)代碼示例演示

從中克隆代碼: 山月博客的 github 倉庫

文件結(jié)構(gòu)

  • index.js: jsonp 的簡單與復(fù)雜實現(xiàn)
  • server.js: 服務(wù)器接口形式
  • demo.html: 前端如何調(diào)用 JSONP

快速演示

 
 
 
 
  1. // 開啟服務(wù)端
  2. $ node server.js
  3. // 對 demo.html 起一個服務(wù),并且按照提示在瀏覽器中打開地址,應(yīng)該是 http://localhost:5000
  4. // 觀察控制臺輸出 JSONP 的回調(diào)結(jié)果
  5. $ serve .

本文轉(zhuǎn)載自微信公眾號「全棧成長之路」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系全棧成長之路公眾號。


網(wǎng)站名稱:頭條面試官:一文徹底搞懂JSONP
分享地址:http://www.dlmjj.cn/article/dhepees.html