深入剖析jsonp跨域

一、jsonp跨域是什麼

1、由來

在Web應用中,為了保證用戶瀏覽的速度,許多網頁會採用Ajax技術在頁面上進行部分刷新,在這個過程中,為了保護用戶的信息和系統的安全,伺服器放置了許多控制訪問的機制,如同源策略(Same Origin Policy)。這個策略禁止一個網頁去調用另一個來源的頁面上的資源。例如,stogege.com的網頁腳本無法取得www.google.com的內容,因為它們不是同源。

但有些情況下,我們需要在不同的域名或埠之間進行數據交互,這時候就需要使用jsonp跨域技術。

2、原理

JSONP(「JSON with padding」)是JSON的一種「使用模式」,可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。Jsonp的實現方法就是在伺服器端加上一個回調函數,然後返回時將數據作為這個回調函數的參數,然後客戶端通過 script 標籤引入這個 URL,就可以拿到遠程返回的 JS 代碼,並在回調函數裡面拿到拿到數據了。由於同源策略的限制,XmlHttpRequest無法跨越域名獲取數據,而script標籤的SRC屬性是沒有跨域限制的。這樣適用JSONP實現跨域數據請求。

// client端
function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}
 
window.onload = function () {
  addScriptTag('http://domain2.com:8080/login?user=admin&callback=foo');
};
 
function foo(data) {
  alert('Your name is ' + data.name);
}
 
// server端
if (url.parse(req.url, true).pathname === '/login') {
  var data = {name: 'admin'};
  var callback = url.parse(req.url, true).query.callback;
  if (callback) {
    res.end(callback + '(' + JSON.stringify(data) + ')');   
  } else {
    res.end(JSON.stringify(data));
  }
}

二、jsonp的優缺點

1、優點

(1)兼容性好:JSONP在實現上比較簡單,在老式瀏覽器上都可以兼容正常使用;

(2)能夠使用不同源下的已存在的服務:JSONP通過script標籤來調用,無須Ajax的標準化支持,因此可以跨越不同源而無需要後台支持;

2、缺點

(1)可讀性差:JSONP返回的數據要求是JSON格式的,這種格式對於閱讀來說不太友好,可讀性差;

(2)不安全:JSONP是可以進行跨域操作的,也就意味著當被請求的服務存在安全漏洞時,這種操作可能會導致一定的安全風險,代碼難以維護。

三、jsonp的應用場景

1、富客戶端Web應用

富客戶端Web應用通常需要動態獲取各種數據,這些數據通常來自不同的域名,而JSONP正是一種跨域的手段,使得這些數據能夠被成功地獲取。

2、第三方數據解析

第三方的數據解析通常有兩種方式:一個是通過後台進行轉發,另外一個就是使用JSONP來實現,將解析到的數據直接返回到前端,使用JSONP進行數據解析。

四、jsonp的實現過程

1、前端請求

function jsonp(url, params, callback) {
  const script = document.createElement('script');
  const src = url + '?' + jsonpParams(params, callback);
  script.setAttribute('src', src);
  document.body.appendChild(script)
}
function jsonpParams(params, callback) {
  let str = '';
  const callbackName = 'jsonp_callback_' + parseInt(+new Date() / 1000);
  window[callbackName] = (data) => {
    try {
      callback && callback(data);
    } catch (e) {}
    delete window[callbackName];
    document.body.removeChild(script);
  };
  str = 'callback=' + callbackName;
  for (let key in params) {
    str += '&' + key + '=' + params[key];
  }
  return str;
}
jsonp('http:// domain2.com:8080/login', {user: 'admin'}, (data) => {
  console.log(data);
});

2、後端響應

if (/^\/api\/jsonp$/i.test(req.pathname)) {
  const data = JSON.stringify({id: 1, name: 'test'});
  res.end(`${req.query.callback}(${data})`);
}

五、jsonp的安全問題

使用JSONP跨域時,由於callback參數不是用戶手動輸入的,而是後台修改後返回給前端的,所以不會被攻擊者通過輸入腳本的方式進行攻擊。但是如果不對服務端返回的數據進行過濾的話,就會存在XSS攻擊的風險。使用JSONP跨域時,服務端應該僅返回經過校驗的、安全的數據。

六、總結

jsonp跨域技術是在Web應用的開發中經常使用的一種技術手段。雖然它有許多限制和不足,但因其簡單易懂,兼容性好,能夠優雅地解決同源策略問題,而被廣泛應用於Web應用的開發中。

原創文章,作者:ESKRE,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/317447.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ESKRE的頭像ESKRE
上一篇 2025-01-11 16:27
下一篇 2025-01-11 16:27

相關推薦

  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、位元組與比特 在討論byte轉int之前,我們需要了解位元組和比特的概念。位元組是計算機存儲單位的一種,通常表示8個比特(bit),即1位元組=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟體,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一個程序就是一個模塊,而一個模塊可以引入另一個模塊,這樣就形成了包。包就是有多個模塊組成的一個大模塊,也可以看做是一個文件夾。包可以有效地組織代碼和數據…

    編程 2025-04-25
  • 深入理解Python字元串r

    一、r字元串的基本概念 r字元串(raw字元串)是指在Python中,以字母r為前綴的字元串。r字元串中的反斜杠(\)不會被轉義,而是被當作普通字元處理,這使得r字元串可以非常方便…

    編程 2025-04-25
  • 深入剖析MapStruct未生成實現類問題

    一、MapStruct簡介 MapStruct是一個Java bean映射器,它通過註解和代碼生成來在Java bean之間轉換成本類代碼,實現類型安全,簡單而不失靈活。 作為一個…

    編程 2025-04-25
  • 深入探討馮諾依曼原理

    一、原理概述 馮諾依曼原理,又稱「存儲程序控制原理」,是指計算機的程序和數據都存儲在同一個存儲器中,並且通過一個統一的匯流排來傳輸數據。這個原理的提出,是計算機科學發展中的重大進展,…

    編程 2025-04-25

發表回復

登錄後才能評論