前端跨域方法 手寫jsonp

什麼是跨域

  • 瀏覽器同域策略要求協議、域名、 端口,都同樣,只要一種不知足都屬於跨域。

跨域有哪一些問題

一、沒法獲取非同源的cookie、localStorge,sensionStorge, indexedDB,ajax

二、 iframe 頁面沒法獲取express

三、 沒法發送ajax,fetch 請求,瀏覽器拒絕,須要服務端支持跨域設置CORS:json

  • 服務端設置響應頭容許來源:
"Access-Control-Allow-Origin", "*"
複製代碼
  • 服務端設置響應頭容許cookie: 服務端 設置Access-Control-Allow-Credentials爲true, XMLHttpRequest的withCredentials爲true,跨域容許cookie發送
response.setHeader("Access-Control-Allow-Origin", "*");
複製代碼
  • 服務端設置響應頭容許methods:
response.setHeader("Access-Control-Allow-Methods", "*");
複製代碼
  • 服務端設置容許響應頭暴露:
response.setHeader("Access-Control-Expose-Headers", "*");
複製代碼
  • 服務端設置請求的存儲時間
response.setHeader("Access-Control-Max-Age", "3600");
複製代碼

js常見的跨域方式:(未完)

一、經過jsonp 跨域

  • JSONP(JSON with Padding)是數據格式 JSON 的一種「使用模式」,可讓網頁從別的網域要數據。
  • 根據 XmlHttpRequest 對象受到同源策略的影響,而利用 <script> 元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的JSON數據,而這種使用模式就是所謂的 JSONP。
  • 用JSONP抓到的數據並非JSON,而是任意的JavaScript,用 JavaScript解釋器運行而不是用JSON解析器解析。
  • 全部,經過Chrome查看全部JSONP發送的Get請求都是js類型,而非 XHR

缺點

  • 只能使用Get請求
  • 不能註冊 success、error 等事件監聽函數,不能很容易的肯定 JSONP 請求是否失敗
  • JSONP 是從其餘域中加載代碼執行,容易受到xss跨站請求僞造的攻擊.

步驟:

  • 1.將傳入的data數據轉化爲url字符串形式
  • 2.處理url中的回調函數
  • 3.建立一個script標籤並插入到頁面中
  • 4.掛載回調函數

jsonp 代碼實現

function encodeParam(url, obj) {
     // 1.將傳入的data數據轉化爲url字符串形式
     // {id:1,name:'jack'} => id=1&name=jack
     const dataString = url.indexof('?') ? '?' : '&';
     for(let key in data) {
       dataString += `${key}=${(data[key] !== undefinded ? data[key] : '' }`
     }
     return dataString;
  }
  const jsonp = function (url, data, callback) {
  //promise 返回 new Promise((resolve, reject)=>{...callback(data)-->resolve(data)...})
      let dataString = encodeParam(url, data);
      // 處理url 中的回調函數
      const cbfnName = `my_json_cb_${Math.ramdom().toString().repalce('.', '')}`;
      
      dataString += `callback=${cbfnName}`;
      
      // 3.建立一個script標籤並插入到頁面
      
      const scriptEle = document.createElement('script');
      scriptEle.src = `${url}${dataString}`
      
      // 四、掛載回調函數
      
      window[cbfnName] = function(data) {
        callback(data); 
        // 處理完回調函數的數據以後,刪除jsonp的script標
        document.body.removeChild(scriptEle);
      }
      document.body.appendChild(scriptEle);    
  }
複製代碼

服務端代碼

let express = require('express');
let app = express();
app.get('/student', function(req, res) {
  let {...callback...} = res.query;
  res.end(`${callback}(data)`)
})
複製代碼
相關文章
相關標籤/搜索