2021-10-12 前端達(dá)人
在我們了解JSONP 和 CORS 之前我們先明確一下:
實(shí)際上,cors和jsonp都是用于解決跨域問題,當(dāng)兩個頁面的協(xié)議、域名、端口號中有一個不一致時就存在了跨域,一旦出現(xiàn)跨域,瀏覽器發(fā)送跨域請求后,請求回來的數(shù)據(jù)都會被瀏覽器所攔截,準(zhǔn)備一張圖給大家看看:
現(xiàn)下實(shí)現(xiàn)跨域數(shù)據(jù)請求,最主要的兩種解決方案分別是 JSONP 和 CORS 。
JSONP
(???)
JSONP
(JSON with Padding
) 是 JSON
的一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。
JSONP
的實(shí)現(xiàn)原理(???)
概念:瀏覽器端通過 <script>
標(biāo)簽的 src
屬性,請求服務(wù)器上的數(shù)據(jù),同時,服務(wù)器返回一個函數(shù)的調(diào)用。這種請求數(shù)據(jù)的方式叫做 JSONP
特點(diǎn):
JSONP
不屬于真正的 Ajax
請求,因?yàn)樗鼪]有使用 XMLHttpRequest
這個對象
JSONP
僅支持 GET
請求,不支持 POST
、PUT
、DELETE
等請求
CORS
(跨域資源共享) 由一系列 HTTP
響應(yīng)頭組成,這些 HTTP
響應(yīng)頭決定瀏覽器 是否阻止前端 JS 代碼跨域獲取資源
瀏覽器的同源安全策略默認(rèn)會阻止網(wǎng)頁“跨域”獲取資源。但如果接口服務(wù)器配置了 CORS 相關(guān)的 HTTP 響應(yīng)頭,就可以解除瀏覽器端的跨域訪問限制
index.html文件代碼演示:
-
<!DOCTYPE html>
-
<html lang="en">
-
-
<head>
-
<meta charset="UTF-8">
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-
<title>Document</title>
-
<script src="jquery.min.js"></script>
-
</head>
-
-
<body>
-
<button class="get">get請求</button>
-
<button class="post">post請求</button>
-
<script>
-
$('.get').on('click', function() {
-
$.ajax({
-
method: 'get',
-
url: 'http://127.0.0.1/api/get?name=hua&age=18',
-
success: function(res) {
-
console.log(res);
-
}
-
})
-
})
-
$('.post').on('click', function() {
-
$.ajax({
-
method: 'post',
-
url: 'http://127.0.0.1/api/post',
-
data: {
-
name: 'lajitong',
-
age: '111'
-
},
-
success: function(res) {
-
console.log(res);
-
}
-
})
-
})
-
</script>
-
</body>
-
-
</html>
此時會出現(xiàn)跨域問題,我們需要使用 cors 中間件解決跨域問題
cors 是 Express 的一個第三方中間件。通過安裝和配置 cors 中間件,可以很方便地解決跨域問題
使用步驟
安裝中間件: npm install cors
導(dǎo)入中間件: const cors = require('cors')
配置中間件: 在路由之前調(diào)用app.use(cors())
express接口案例代碼
-
// 導(dǎo)入 express 模塊
-
const express = require('express')
-
-
// 創(chuàng)建 express 的服務(wù)器實(shí)例
-
const app = express()
-
-
// 導(dǎo)入中間件
-
const cors = require('cors')
-
// 配置中間件
-
app.use(cors())
-
-
// 配置解析表單數(shù)據(jù)的中間件
-
app.use(express.urlencoded({ extended: false }))
-
-
// 導(dǎo)入路由模塊(被單獨(dú)分離后導(dǎo)入)
-
const router = require('./apiRouter')
-
// 把路由模塊,注冊到 app 上
-
app.use('/api', router)
-
-
// 調(diào)用 app.listen 方法,指定端口號并啟動 web 服務(wù)器
-
app.listen(80, () => {
-
console.log('http://127.0.0.1')
-
})
apiRouter路由文件代碼:
-
const express = require('express');
-
const router = express.Router();
-
-
router.get('/get', (req, res) => {
-
const query = req.query;
-
res.send({
-
status: 0,
-
msg: 'get請求成功',
-
data: query
-
})
-
})
-
router.post('/post', (req, res) => {
-
// const body = req.body; //獲取客戶端請求的數(shù)據(jù)
-
res.send({
-
status: 0,
-
msg: 'post請求成功',
-
data: req.body
-
})
-
})
-
module.exports = router;
在終端中運(yùn)行express接口代碼后打開index.html文件并點(diǎn)擊get及post按鈕得到請求結(jié)果:
創(chuàng)建 JSONP
接口的注意事項(xiàng)
如果項(xiàng)目中已經(jīng)配置了 CORS
跨域資源共享,為了防止沖突,必須在配置 CORS
中間件之前聲明 JSONP
的接口
否則 JSONP
接口會被處理成開啟了 CORS
的接口
實(shí)現(xiàn)步驟:
(1)獲取客戶端發(fā)送過來的回調(diào)函數(shù)的名字
(2)得到要通過 JSONP
形式發(fā)送給客戶端的數(shù)據(jù)
(3)根據(jù)前兩步得到的數(shù)據(jù),拼接出一個函數(shù)調(diào)用的字符串
(4)把上一步拼接得到的字符串,響應(yīng)給客戶端的 <script>
標(biāo)簽進(jìn)行解析執(zhí)行
案例代碼如下:
-
//導(dǎo)入express模塊
-
const express = require('express');
-
//創(chuàng)建express服務(wù)器實(shí)例
-
const app = express();
-
//掛載路由
-
app.get('/jsonp', (req, res) => {
-
// 通過解構(gòu)req.query客戶端通過查詢字符串的形式發(fā)送到客戶端的參數(shù)fn
-
const { callback } = req.query
-
//在服務(wù)器端定義一個obj對象
-
const obj = {
-
uname: 'zjj',
-
age: '18'
-
}
-
//obj對象轉(zhuǎn)為res.send可處理的字符串形式后從服務(wù)器端相應(yīng)回調(diào)函數(shù)至客戶端
-
res.send(`${callback}(${JSON.stringify(obj)})`)
-
})
-
app.listen(80, () => {
-
console.log('http://127.0.0.1');
-
})
創(chuàng)建jsonp.html客戶端來接收服務(wù)器端響應(yīng)過來的回調(diào)函數(shù),代碼如下:
url中callback=fn為客戶端發(fā)送請求攜帶的參數(shù) 既服務(wù)器端中的req.query.callback
-
<script>
-
function fn(res) {
-
console.log(res);
-
}
-
</script>
-
<script src="http://127.0.0.1/jsonp?callback=fn"></script>
分享此文一切功德,皆悉回向給文章原作者及眾讀者.
轉(zhuǎn)自:csdn
免責(zé)聲明:藍(lán)藍(lán)設(shè)計尊重原作者,文章的版權(quán)歸原作者。如涉及版權(quán)問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。
藍(lán)藍(lán)設(shè)計( www.yvirxh.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)
藍(lán)藍(lán)設(shè)計的小編 http://www.yvirxh.cn