wordpress 中英文網(wǎng)站模板軟文寫(xiě)手接單平臺(tái)
目錄
1、瀏覽器的同源策略
1.1 源
1.2 同源與非同源
1.3 同源請(qǐng)求與非同源請(qǐng)求
2、跨域受到的限制
3、注意點(diǎn)
4、CORS解決Ajax跨域問(wèn)題
4.1 CORS概述
4.2 CORS解決簡(jiǎn)單請(qǐng)求跨域
4.3 簡(jiǎn)單請(qǐng)求與復(fù)雜請(qǐng)求
4.4 CORS解決復(fù)雜請(qǐng)求跨域
4.5 借助CORS庫(kù)快速完成配置
5、JSONP解決跨域?
6、配置代理解決跨域
6.1 自己配置代理服務(wù)器
6.2 使用Nginx搭建代理服務(wù)器
6.3 借助腳手架搭建代理服務(wù)器
1、瀏覽器的同源策略
瀏覽器為了確保資源安全,而遵循的一種策略。
1.1 源
源 = 協(xié)議 + 域名 + 端口號(hào)
1.2 同源與非同源
1.3 同源請(qǐng)求與非同源請(qǐng)求
所處源與目標(biāo)源不一致,就是非同源,又稱(chēng)異源或跨域
2、跨域受到的限制
例如:源A和源B,它們是非同源,則瀏覽器會(huì)有如下限制
- DOM訪問(wèn)限制:源A的腳本不能讀取和操作源B的DOM
- Cookie訪問(wèn)限制:源A不能訪問(wèn)源B的cookie
- Ajax響應(yīng)數(shù)據(jù)限制:源A可以給源B發(fā)請(qǐng)求,但是無(wú)法獲取源B的響應(yīng)的數(shù)據(jù)
備注:在上述限制中,瀏覽器對(duì)Ajax獲取數(shù)據(jù)的限制是影響最大的一個(gè),且實(shí)際開(kāi)發(fā)中經(jīng)常遇到
3、注意點(diǎn)
- 跨域限制僅存在瀏覽器端,服務(wù)端不存在跨域限制
- 即使跨域了,Ajax請(qǐng)求也可以正常發(fā)出,但響應(yīng)數(shù)據(jù)不會(huì)交給開(kāi)發(fā)者
- <link>、<script>、<img>....這些標(biāo)簽發(fā)出的請(qǐng)求也可能跨域,只不過(guò)瀏覽器對(duì)標(biāo)簽跨域不做嚴(yán)格限制,對(duì)開(kāi)發(fā)幾乎無(wú)影響
4、CORS解決Ajax跨域問(wèn)題
4.1 CORS概述
CORS全稱(chēng):Cross-Origin Resource Sharing(跨域資源共享),是用于控制瀏覽器校驗(yàn)跨域請(qǐng)求的一套規(guī)范,服務(wù)器依照CORS規(guī)范,添加特定響應(yīng)頭來(lái)控制瀏覽器校驗(yàn),規(guī)則如下:
- 服務(wù)器明確表示拒絕跨域請(qǐng)求,或沒(méi)有表示,則瀏覽器校驗(yàn)不通過(guò)
- 服務(wù)器明確表示允許跨域請(qǐng)求,則瀏覽器校驗(yàn)通過(guò)
備注:使用CORS解決跨域是最正統(tǒng)的方式,且要求服務(wù)器是“自己人”
4.2 CORS解決簡(jiǎn)單請(qǐng)求跨域
整體思路:服務(wù)器在給出響應(yīng)時(shí),通過(guò)添加Access-Control-Allow-Origin響應(yīng)頭,來(lái)明確表達(dá)允許某個(gè)源發(fā)起跨域請(qǐng)求,隨后瀏覽器在校驗(yàn)時(shí),直接通過(guò)
服務(wù)端核心代碼,以(express框架為例)
const express = require('express')const app = express()const data = [{ id: 123, name: '張三' },{ id: 456, name: '李四' },{ id: 789, name: '趙云' }, ] app.get('/student', (req, res) => {res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')res.send(data) })app.listen(1234, () => {console.log('服務(wù)運(yùn)行中...') })
4.3 簡(jiǎn)單請(qǐng)求與復(fù)雜請(qǐng)求
CORS會(huì)把請(qǐng)求分為兩類(lèi)、分別是:簡(jiǎn)單請(qǐng)求、復(fù)雜請(qǐng)求
簡(jiǎn)單請(qǐng)求 復(fù)雜請(qǐng)求 請(qǐng)求方法為:GET、HEAD、POST
- 不是簡(jiǎn)單請(qǐng)求,就是復(fù)雜請(qǐng)求
- 復(fù)雜請(qǐng)求會(huì)自動(dòng)發(fā)送預(yù)檢請(qǐng)求
請(qǐng)求字段要符合《CORS安全規(guī)范》
簡(jiǎn)記:只要不手動(dòng)修改請(qǐng)求頭,一般都能符合改規(guī)范
請(qǐng)求頭的Content-Type的值只能是以下三種
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
關(guān)于預(yù)檢請(qǐng)求:
- 發(fā)送時(shí)機(jī):預(yù)檢請(qǐng)求再實(shí)際跨域請(qǐng)求之前發(fā)出,是由瀏覽器自動(dòng)發(fā)起的
- 主要作用:用于向服務(wù)器確認(rèn)是否允許接下來(lái)的跨域請(qǐng)求
- 基本流程:先發(fā)起OPTIONS請(qǐng)求,如果通過(guò)預(yù)檢,繼續(xù)發(fā)起實(shí)際的跨域請(qǐng)求
- 請(qǐng)求頭內(nèi)容:一個(gè)OPTIONS預(yù)檢請(qǐng)求,通常會(huì)包含如下請(qǐng)求頭
請(qǐng)求頭 含義 Origin? ? ?? 發(fā)起請(qǐng)求的源 Access-Control-Request-Method 實(shí)際請(qǐng)求的HTTP方法 Access-Control-Request-Headers 實(shí)際請(qǐng)求中使用的自定義頭(如果有的話)
4.4 CORS解決復(fù)雜請(qǐng)求跨域
1、第一步:服務(wù)器先通過(guò)瀏覽器的預(yù)檢請(qǐng)求,服務(wù)器需要返回如下響應(yīng)頭
響應(yīng)頭 含義 Access-Control-Allow-Origin 允許的源 Access-Control-Allow-Methods 允許的方法 Access-Control-Allow-Headers 允許的自定義頭 Access-Control-Max-Age
預(yù)檢請(qǐng)求的結(jié)果緩存時(shí)間(可選) 服務(wù)端核心代碼:
const express = require('express')const app = express()const data = [{ id: 123, name: '張三' },{ id: 456, name: '李四' },{ id: 789, name: '趙云' }, ]app.options('/student', (req, res) => {res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')res.setHeader('Access-Control-Allow-Method', 'GET')res.setHeader('Access-Control-Allow-Headers', 'a,b,c')res.setHeader('Access-Control-Allow-Age', 9000)res.send() })app.get('/student', (req, res) => {res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')res.send(data) })app.listen(1234, () => {console.log('服務(wù)運(yùn)行中...') })
4.5 借助CORS庫(kù)快速完成配置
上述的配置中需要自己配置響應(yīng)頭,或者需要自己手動(dòng)封裝中間件,借助cors庫(kù),可以更方便完成配置
1、安裝cors
npm i cors
2、簡(jiǎn)單配置
app.use(cors())
3、完整配置
const corsOption = {origin: 'http://127.0.0.1:5500', // 允許的源methods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'], // 允許的方法allowedHeaders: [], // 允許的自定義頭exposedHeaders: [], // 要暴露的響應(yīng)頭optionsSuccessStatus: 200, // 預(yù)檢請(qǐng)求成功的狀態(tài)碼 } app.use(cors(corsOption))
5、JSONP解決跨域?
1、JSONP概述:JSONP是利用了<script>標(biāo)簽可以跨域加載腳本,且不受?chē)?yán)格限制的特性,可以說(shuō)是程序員智慧的結(jié)晶,早起一些瀏覽器不支持CORS時(shí),可以靠JSONP解決跨域
2、基本流程
- 第一步:客戶(hù)端創(chuàng)建一個(gè)<script>標(biāo)簽,并將其src屬性設(shè)置為包含跨域請(qǐng)求的URL,同時(shí)準(zhǔn)備一個(gè)回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)用于處理返回的數(shù)據(jù)
- 第二步:服務(wù)端接收到請(qǐng)求后,將數(shù)據(jù)封裝在回調(diào)函數(shù)中并返回
- 第三步:客戶(hù)端的回調(diào)函數(shù)被調(diào)用。數(shù)據(jù)以參數(shù)的形式傳入回調(diào)函數(shù)。
3、圖示
4、服務(wù)端核心代碼:
const express = require('express') const app = express()const data = [{ id: 123, name: '張三' },{ id: 456, name: '李四' },{ id: 789, name: '趙云' }, ]app.get('/getData', (req, res) => {res.send(`fn(${JSON.stringify(data)})`) })app.listen(1234, () => {console.log('服務(wù)運(yùn)行中...') })
5、客戶(hù)端核心代碼:
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><button onclick="getData()">獲取數(shù)據(jù)</button></body><script>function fn(data) {console.log(data)}function getData() {const script = document.createElement('script')script.onload = () => {script.remove()}script.src = 'http://127.0.0.1:1234/getData'document.body.appendChild(script)}</script> </html>
6、配置代理解決跨域
6.1 自己配置代理服務(wù)器
借助 http-proxy-middleware 配置代理
const { createProxyMiddleware } = require('http-proxy-middleware')// 攔截所有帶有'/api'的請(qǐng)求,轉(zhuǎn)發(fā)給target app.use('/api',createProxyMiddleware({target: 'https://www.toutiao.com',changOrigin: true, // 允許跨域pathRewrite: {'^/api': '',},}) )
6.2 使用Nginx搭建代理服務(wù)器
1. 安裝 Nginx
首先,你需要在你的服務(wù)器上安裝 Nginx。根據(jù)你的操作系統(tǒng),安裝步驟可能有所不同。
?在 Ubuntu/Debian 系統(tǒng)上:
sudo apt update sudo apt install nginx
在 CentOS/RHEL 系統(tǒng)上:
sudo yum install epel-release sudo yum install nginx
在 Fedora 系統(tǒng)上:
sudo dnf install nginx
安裝完成后,啟動(dòng) Nginx 并設(shè)置開(kāi)機(jī)自啟:
sudo systemctl start nginx sudo systemctl enable nginx
2、配置 Nginx 作為代理服務(wù)器
接下來(lái),配置 Nginx 作為代理服務(wù)器。你可以編輯 Nginx 配置文件,通常在
/etc/nginx/nginx.conf
或/etc/nginx/sites-available/default
,具體路徑根據(jù)操作系統(tǒng)和 Nginx 版本可能有所不同。基本的代理配置示例如下:
- 打開(kāi)配置文件:
sudo nano /etc/nginx/nginx.conf
- 添加一個(gè)
server
塊來(lái)配置代理設(shè)置。例如,假設(shè)你想要將所有請(qǐng)求代理到http://backend-server
:http {...server {listen 80;server_name your-domain.com;location / {proxy_pass http://backend-server; # 后端服務(wù)器的地址proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}}... }
這里的
proxy_pass
指令將請(qǐng)求轉(zhuǎn)發(fā)到http://backend-server
。你可以根據(jù)需要更改為你實(shí)際的后端服務(wù)器地址。
proxy_set_header
指令用于設(shè)置轉(zhuǎn)發(fā)請(qǐng)求時(shí)的 HTTP 頭信息。- 保存文件并退出編輯器。
- 測(cè)試配置是否正確:
sudo nginx -t
- 重新加載 Nginx 配置:
sudo systemctl reload nginx
3、驗(yàn)證代理設(shè)置
現(xiàn)在,你可以通過(guò)訪問(wèn)你的代理服務(wù)器地址來(lái)驗(yàn)證是否能夠成功地將請(qǐng)求代理到后端服務(wù)器。例如,訪問(wèn)
http://your-domain.com
,你應(yīng)該能夠看到來(lái)自http://backend-server
的內(nèi)容。4、其他配置(可選)
根據(jù)需求,你可能還需要進(jìn)行其他配置,例如:
- 負(fù)載均衡: 如果你有多個(gè)后端服務(wù)器,可以使用
upstream
塊來(lái)進(jìn)行負(fù)載均衡。- SSL/TLS 加密: 如果你需要 HTTPS,可以配置 SSL 證書(shū)來(lái)加密代理流量。
- 緩存: 配置 Nginx 緩存以提高性能。
6.3 借助腳手架搭建代理服務(wù)器
修改
vue.config.js
文件:// vue.config.js module.exports = {devServer: {proxy: 'http://localhost:5000', // 代理到你的后端服務(wù)器// 或者使用對(duì)象形式配置多個(gè)代理/*proxy: {'/api': {target: 'http://localhost:5000',changeOrigin: true,pathRewrite: { '^/api': '' },},},*/}, };