91网首页-91网页版-91网在线观看-91网站免费观看-91网站永久视频-91网站在线播放

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

【W(wǎng)EB開(kāi)發(fā)】什么是“跨域”及跨域解決方案

admin
2025年2月21日 16:1 本文熱度 1267
什么是跨域

跨域是指從一個(gè)域名的網(wǎng)頁(yè)去請(qǐng)求另一個(gè)域名的資源。比如,從www.a.com域名的網(wǎng)頁(yè)去請(qǐng)求www.b.com域名的資源,只要協(xié)議、域名、端口有任何一個(gè)不同,都被當(dāng)作是不同的域,跨域問(wèn)題通常由瀏覽器的同源策略引起的。

同源策略就是瀏覽器出于安全考慮而制定的,例如數(shù)據(jù)安全,服務(wù)器安全,減少 xss(跨站腳本攻擊),CSRF(跨站請(qǐng)求偽造) 等攻擊。所謂同源,就是協(xié)議,域名,端口號(hào)都相同才能請(qǐng)求數(shù)據(jù)。如果是非同源請(qǐng)求發(fā)送后,瀏覽器會(huì)攔截響應(yīng)。

  1. 瀏覽器出于安全考慮(數(shù)據(jù)安全,服務(wù)器安全,減少 xss,CSRF 攻擊)  2. https://    www.     abc.com    :8000     /a.html      協(xié)議      子域名     主域名     端口號(hào)   路徑  3. 非同源,請(qǐng)求發(fā)送后,瀏覽器會(huì)攔截響應(yīng)

跨域解決方案

1.jsonp

  1. 借助 script 標(biāo)簽 src 屬性不受同源策略的限制(經(jīng)常要加載第三方庫(kù)等),來(lái)發(fā)送請(qǐng)求
  2. 攜帶一個(gè)參數(shù) callback 給后端
  3. 后端將數(shù)據(jù)作為 callback 函數(shù)的實(shí)參,返回給前端一個(gè) callback 的調(diào)用形式
  4. 瀏覽器接收到 callback 的調(diào)用會(huì)自動(dòng)執(zhí)行全局的callback函數(shù)

代碼具體實(shí)現(xiàn)如下:
// 前端<button onclick="handle()">請(qǐng)求</button>
<script>    function jsonp(url, cb) {      return new Promise((resolve, reject) => {
        const script = document.createElement('script')
        // 定義一個(gè)全局函數(shù),用來(lái)接收后端返回的數(shù)據(jù)        window[cb] = function (data) {          // console.log(data) // 后端返回的數(shù)據(jù)          resolve(data)        }
        script.src = `${url}?cb=${cb}`
        // 將標(biāo)簽加到document.body時(shí),瀏覽器就會(huì)發(fā)url請(qǐng)求        document.body.appendChild(script)          // callback('hello world')      })    }
    function handle() {      jsonp('http://localhost:3000', 'callback').then(res => {        console.log(res)      })    } </script>
前端通過(guò)一個(gè)jsonp函數(shù),傳入請(qǐng)求的url和回調(diào)函數(shù)的名稱(chēng)cb,然后在jsonp函數(shù)里面創(chuàng)建一個(gè)script標(biāo)簽,將該標(biāo)簽的src屬性變?yōu)閡rl后面用?拼接傳入的字符串。
// 后端const http = require('http');
http.createServer((req, res) => {  // 獲取前端傳過(guò)來(lái)參數(shù)  const query = new URL(req.url, `http://${req.headers.host}`).searchParams
  if (query.get('cb')) {    const cb = query.get('cb')  // 'callback'    const data = 'hello world'    const result = `${cb}("${data}")`   // "callback('hello world')"    res.end(result)  }
}).listen(3000);

后端創(chuàng)建一個(gè)http服務(wù)器,解析前端傳過(guò)來(lái)的callback字符串參數(shù),將數(shù)據(jù)作為參數(shù)返回"callback('hello world')"格式的一個(gè)函數(shù)。

缺點(diǎn):

  • 必須要前后端配合
  • 只能發(fā)送 get 請(qǐng)求
  • 不安全,容易受到xss攻擊

2. CORS(跨資源共享)

服務(wù)器在響應(yīng)頭中后端設(shè)置 Access-Control-Allow-Origin: '域名白名單',告訴瀏覽器允許哪個(gè)源進(jìn)行跨域訪問(wèn)。可以是具體的域名,也可以是*表示允許所有源。如下

const http = require('http')
const server = http.createServer((req, res) => {  res.writeHead(200, {    'Access-Control-Allow-Origin''*',    // 允許所有域名訪問(wèn)    // 也可自行設(shè)置指定的域名可以訪問(wèn)     // 例如: 'Access-Control-Allow-Origin': 'http://192.168.2.1:5500'  })  res.end('hello world');})
server.listen(3000)
還可設(shè)置允許的請(qǐng)求方式和請(qǐng)求頭等。

3.nginx反向代理

前端服務(wù)器和后端服務(wù)器不在同一個(gè)域名下, 前端服務(wù)器通過(guò)nginx 反向代理來(lái)訪問(wèn)后端服務(wù)器。

服務(wù)器和服務(wù)器之間的通信不存在跨域,可以開(kāi)一臺(tái)中間服務(wù)器(nginx),后端無(wú)需改變。前端把請(qǐng)求發(fā)給nginx , nginx 服務(wù)器把請(qǐng)求轉(zhuǎn)發(fā)給后端的服務(wù)器,后端的服務(wù)器響應(yīng)給 nginx 服務(wù)器,nginx 服務(wù)器加上響應(yīng)頭以后,再返回給前端,如下;

4. node 中間件代理

原理同nginx 反向代理,只不過(guò)多寫(xiě)一個(gè)node后端,前端服務(wù)器和后端服務(wù)器不在同一個(gè)域名下,前端服務(wù)器通過(guò) node 中間件來(lái)訪問(wèn)后端服務(wù)器。

5. websocket

  1. 傳統(tǒng)的前后端通信是基于http協(xié)議的,是單向的,只能從一端發(fā)到另一端,無(wú)法雙向通信
  2. websocket 是基于tcp協(xié)議的,是雙向的,可以從一端發(fā)送到另一端,也可以從另一端發(fā)送到一端
  3. socket協(xié)議一旦建立連接,就可以一直保持通信狀態(tài),不需要每次都建立連接,但是會(huì)更開(kāi)銷(xiāo)性能
  4. 天生就可以跨域

// 前端<script>    function WebSocketTest(url, params = {}) {      return new Promise((resolve, reject) => {
        // 創(chuàng)建socket實(shí)例對(duì)象        const socket = new WebSocket(url)
        // 當(dāng)連接打開(kāi)時(shí)發(fā)送數(shù)據(jù)        socket.onopen = () => {          socket.send(JSON.stringify(params))        }
        // 接收到后端的消息時(shí)打印數(shù)據(jù)并解決Promise        socket.onmessage = (event) => {          console.log(event.data)          resolve(event.data)        }      })    }
    WebSocketTest('ws://localhost:3000', { age: 18 }).then(res => {      console.log(res)    })  </script>
后端: 首先安裝ws:npm i ws
// 后端
const WebSocket = require('ws');
// 在 3000 端口上建立 WebSocket 伺服器 (隨時(shí)都在線的服務(wù))const ws = new WebSocket.Server({ port: 3000 });
let count = 0
// 監(jiān)聽(tīng)連接ws.on('connection', (obj) => {  // console.log(obj);  obj.on('message', (msg) => {  // 收到客戶(hù)端發(fā)來(lái)的消息    // console.log(msg.toString());   // 客戶(hù)端傳過(guò)來(lái)的數(shù)據(jù)    obj.send('收到了')
    setInterval(() => {      count++      obj.send(count)    }, 2000)
  })})

6. postMessage

當(dāng)父級(jí)頁(yè)面和iframe頁(yè)面不在同一個(gè)域名下,他們之間的數(shù)據(jù)傳輸也存在跨域問(wèn)題,父級(jí)頁(yè)面和iframe頁(yè)面之間可以通過(guò)posMessage來(lái)通信。

<h2>首頁(yè)</h2><iframe id="frame" src="http://127.0.0.1:5500/%E8%B7%A8%E5%9F%9F/postMessage/detail.html"frameborder="0" width="800" height="500"></iframe>
<script>    let obj = { name'阿杰'age18 }
    document.getElementById('frame').onload = function () {      this.contentWindow.postMessage(obj, 'http://127.0.0.1:5500'// 向iframe發(fā)送消息
      window.onmessage = function (e) { // 接收iframe發(fā)送的消息        console.log(e.data);      }
    }  </script>
<h3>詳情頁(yè) --- <span id="title"></span></h3>
<script>    const title = document.getElementById("title");    window.onmessage = function (e) {  // 接收父級(jí)頁(yè)面?zhèn)鬟^(guò)來(lái)的數(shù)據(jù)      // console.log(e.data);      title.innerText = e.data.age;      e.source.postMessage("阿杰 20了", e.origin)  // 向父級(jí)頁(yè)面發(fā)送消息    }  </script>

7.document.domain

通過(guò)設(shè)置document.domain來(lái)允許同一主域名下的跨域通信,原理同postMessage,但是谷歌禁止了這種方法

總結(jié)

跨域是指從一個(gè)域名的網(wǎng)頁(yè)去請(qǐng)求另一個(gè)域名的資源。只要協(xié)議、域名、端口有任何一個(gè)不同,都被當(dāng)作是不同的域。跨域問(wèn)題通常由瀏覽器的同源策略引起,同源策略是為了保證用戶(hù)信息的安全,防止惡意網(wǎng)站竊取數(shù)據(jù)

同源策略瀏覽器出于安全考慮(數(shù)據(jù)安全,服務(wù)器安全,減少 xss,CSRF 攻擊)而制定的一種只有協(xié)議、域名、端口號(hào)都相同才能請(qǐng)求數(shù)據(jù)的規(guī)定,非同源請(qǐng)求發(fā)送后,瀏覽器會(huì)攔截響應(yīng)。

跨域方案

  1. jsonp(script標(biāo)簽的src屬性不受同源策略的限制)
  2. CORS(跨資源共享,通知瀏覽器哪些域名可以訪問(wèn))
  3. nginx 反向代理
  4. node 中間件代理
  5. websocket(socket協(xié)議可以保持長(zhǎng)時(shí)間的連接,不受同源的限制,天生可以跨域)
  6. postMessage(父級(jí)頁(yè)面和iframe頁(yè)面之間可以通過(guò)posMessage來(lái)通信)
  7. document.domain(通過(guò)設(shè)置來(lái)允許同一主域名下的跨域通信,谷歌禁止了)

常見(jiàn)的解決方案有:CORS適用于需要支持多種HTTP方法(如GET、POST、PUT等)的現(xiàn)代Web應(yīng)用,nginx 反向代理適用于前后端分離的項(xiàng)目,可以在服務(wù)器層面統(tǒng)一處理跨域問(wèn)題。


該文章在 2025/2/21 16:01:37 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶(hù)的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 日韩一A | 日韩高清电影 | 国产网站免费视频 | 91精品污| 欧美一级操穴 | 国产性天天综合网 | 国产精品成人 | 日韩午夜福| 国精品片在线视频 | 91成人小视频 | 国产学生情侣偷 | 国产欧美丝袜在 | 国产精品国产三 | 国产91精品 | 国产啪精品视频网站 | 亚洲无码午间福利小电影 | 午夜国产更新 | 中文字幕丰 | 国产高清视频在线 | 日本国产一区 | 国产偷亚洲 | 三级网址在线观看 | 国产狂喷潮在线 | 欧美午夜在线看片网 | 精品国产一区 | 国产色a在线观看 | 国产精品秘A级导航 | 人操人碰 | 日产国产一区二区 | 国产精品亚洲精 | 绿帽社区在线观看 | 欧洲一级欧美一级a | 精品精品国 | 日本很污很黄小 | 中文字幕日本不卡 | 日本国产 | 国产91中文在 | 中文字幕日韩电影 | 国产韩国欧美在线 | 美乳一区二区 | 韩国十九|