跨域是前端在本地開發程序會經常遇到的問題,有的時候大部分是讓后端童鞋幫忙處理下就好了,哈哈 但是作者有自己的態度,基本都是自己解決這個問題,俗話說自己動手 豐衣足食呀,廢話就不多說了,讓我們來先了解跨域是如何產生的,
1.什么是跨域?
跨域:指的是瀏覽器不能執行其他網站的腳本,它是由瀏覽器的同源策略造成的,是瀏覽器對javascript施加的安全限制,
例如:a頁面想獲取b頁面資源,如果a、b頁面的協議、域名、埠、子域名不同,所進行的訪問行動都是跨域的,而瀏覽器為了安全問題一般都限制了跨域訪問,也就是不允許跨域請求資源,注意:跨域限制訪問,其實是瀏覽器的限制,
同源策略:是指協議,域名,埠都要相同,其中有一個不同都會產生跨域;

跨域示例:后端開發的童鞋已經將介面部署到測驗環境,前端還在本地進行介面除錯階段,此時就會出現跨域

2.如何解決跨域
1.跨檔案通信 API:window.postMessage() 呼叫postMessage方法實作父視窗 A.com 向子視窗 B.com 發訊息(子視窗同樣可以通過該方法發送訊息給父視窗,主要解決以下幾種場景
頁面和其打開的新視窗的資料傳遞
多視窗之間訊息傳遞
頁面與嵌套的iframe訊息傳遞
上面三個場景的跨域資料傳遞
// 父視窗打開一個子視窗
var openWindow = window.open('http://A.com', 'hello');
// 父視窗向子視窗發訊息(第一個引數代表發送的內容,第二個引數代表接收訊息視窗的url)
openWindow.postMessage('how are you', 'http://B.com');
復制代碼
2.JSONP
JSONP 是服務器與客戶端跨源通信的常用方法,最大特點就是簡單適用,兼容性好(兼容低版本IE),缺點是只支持get請求,不支持post請求,
核心思想:網頁通過添加一個
JQ的方式
$.ajax({
url: 'http://A.com/login',
type: 'get',
data: {},
xhrFields: {
withCredentials: true // 前端設定是否帶cookie
},
crossDomain: true, // 會讓請求頭中包含跨域的額外資訊,但不會含cookie
});
復制代碼
原生js引入的方式
var xhr = new XMLHttpRequest();
// 前端設定是否帶cookie
xhr.withCredentials = true;
xhr.open('post', 'http://www.A.com/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
復制代碼
3.Nginx(反向代理)
Nginx處理跨域的方式其實就是反向反向代理,那什么是反向代理呢?通俗一點說就是我們不能直接訪問到目標服務器,這個時候我們就需要通過代理的方式實作,這種對于用戶還是我們開發來說都是無感的,因為這些處理都是nginx幫我們處理好了,配置代碼如下
listen 8081;
server_name localhost 127.0.0.1; //當前服務的域名
#location ~ ^/(yunpos|agent)/ { //添加訪問目錄為/apis的代理配置
#proxy_pass https://manage-api.yingqianpos.com; #線上后臺api
#proxy_pass https://yunpos-manageapi.cs.kemai.com.cn; #測驗后臺api
#}
復制代碼
4.Node服務端代理
1.koa-server-http-proxy是koa2的中間件
const Koa = require('koa')
const app = new Koa()
const proxy = require('koa-server-http-proxy')
app.use(async (ctx, next)=> {
ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
if (ctx.method == 'OPTIONS') {
ctx.body = 200;
} else {
await next();
}
});
app.use(proxy('/yunpos', {
target: 'https://manage-gray.yingqianpos.com',
pathRewrite: { '^/yunpos': '' },
changeOrigin: true
}))
app.listen(8081)
復制代碼
2.# http-proxy-middleware是node.js提供的代理方式
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/yunpos',
createProxyMiddleware({
target: 'https://manage-gray.yingqianpos.com',
changeOrigin: true,
pathRewrite: {
'^/yunpos': '', // rewrite path
},
}));
app.listen(8081)
復制代碼
雖然現在vue、react的框架已經跨域的請求處理,這對我們前端童靴來說是個福音,但是還是存在某些傳統的專案還是需要需要我們通過其他的方式實作跨域請求,node服務端代理以及nginx反向代理目前是我用的最多,
最后
如果你覺得此文對你有一丁點幫助,點個贊,或者可以加入我的開發交流群:1025263163相互學習,我們會有專業的技術答疑解惑
如果你覺得這篇文章對你有點用的話,麻煩請給我們的開源專案點點star:https://gitee.com/ZhongBangKeJi/crmeb_java不勝感激 !
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/389038.html
標籤:其他
