解決跨域有多重,在這裏主要講用nginx解決跨域javascript
nginx下載地址html
前端代碼:
利用jQuery的ajax api發送請求前端
<button id="getOK">發送請求OK(客戶端解決跨域問題)</button> <button id="getNO">發送請求NO(客戶端解決跨域問題)</button> <script> $(document).ready(function () { $('#getOK').click(function () { $.ajax({ url:'http://localhost:3000/ok', success:function(res) { console.log("success",res) }, error:function(err) { console.log('fail',err) } }) }) $('#getNO').click(function () { $.ajax({ url:'http://localhost:3000/no', success:function(res) { console.log("success",res) }, error:function(err) { console.log('fail',err) } }) }) }) </script>
後端代碼:
利用node的express框架開啓服務,並根據url返回json格式的數據,
設置這麼多接口的目的是爲了後面匹配nginx的location配置的java
const express = require('express') const cookieParser = require('cookie-parser') var app = express() var router = express.Router() router.get('/ok',function (req,res) { res.json({ code:200, msg:"isOK" }) }) router.get('/ok/son',function (req,res) { res.json({ code:200, msg:"isOKSon" }) }) router.get('/ok2',function (req,res) { res.json({ code:200, msg:"isOK2" }) }) router.get('/no',function (req,res) { res.json({ code:200, msg:"isNO" }) }) router.get('/no/son',function (req,res) { res.json({ code:200, msg:"isNOSON" }) }) router.get('/no/son2',function (req,res) { res.json({ code:200, msg:"isNOSON2" }) }) app.use(router) app.use(cookieParser) app.listen(3000,function () { console.log('listen in 3000') })
而後開啓node服務
如今能夠測試下接口
能夠看出,node服務成功開啓
如今能夠嘗試不開啓nginx服務直接發送ajax請求會出現什麼狀況
(注意:發送ajax請求須要以服務器方式打開網頁,不能以文件形式)
如圖,在5500端口請求3000端口出現了跨域問題,這時候就能夠開啓nginx服務並配置location進行解決node
反向代理的原理就是講前端的地址和後端的地址用nginx轉發到同一個地址下,如5500端口和3000端口都轉到3003端口下,具體配置以下:jquery
具體的location配置規則以下:
nginx的location配置規則nginx
server { listen 3003; server_name localhost; ## = /表示精確匹配路徑爲/的url,真實訪問爲http://localhost:5500 location = / { proxy_pass http://localhost:5500; } ## /no 表示以/no開頭的url,包括/no1,no/son,或者no/son/grandson ## 真實訪問爲http://localhost:5500/no開頭的url ## 若 proxy_pass最後爲/ 如http://localhost:3000/;匹配/no/son,則真實匹配爲http://localhost:3000/son location /no { proxy_pass http://localhost:3000; } ## /ok/表示精確匹配以ok開頭的url,/ok2是匹配不到的,/ok/son則能夠 location /ok/ { proxy_pass http://localhost:3000; } }
上面代碼的意思是將localhost:3003轉發爲location:5500,也就是說如今訪問localhost:3003其實是訪問location:5500,而訪問localhost:3003/no則是訪問localhost:3000,並以no開頭的urlgit
如今修改前端代碼,將以前請求的接口的端口換爲3003,以下:github
$('#getOK').click(function () { $.ajax({ url:'http://localhost:3003/ok', success:function(res) { console.log("success",res) }, error:function(err) { console.log('fail',err) } }) })
在瀏覽器訪問的也不算location:5500,而是localhost:3003了,再次發送請求也不會出現跨域問題了,由於他們都是同一個域了,這就是nginx反向代理ajax
這是前端代碼
$(document).ready(function () { $('#get').click(function () { $.ajax({ url:'http://localhost:3002/ok', // 帶cookies的請求 xhrFields:{ withCredentials:true }, success:function(res) { console.log("success",res) }, error:function(err) { console.log('fail',err) } }) }) })
後端代碼同前面
還有nginx配置以下:
server { listen 3002; server_name localhost; location /ok { proxy_pass http://localhost:3000; # 指定容許跨域的方法,*表明全部 add_header Access-Control-Allow-Methods *; # 預檢命令的緩存,若是不緩存每次會發送兩次請求 add_header Access-Control-Max-Age 3600; # 帶cookie請求須要加上這個字段,並設置爲true add_header Access-Control-Allow-Credentials true; # 表示容許這個域跨域調用(客戶端發送請求的域名和端口) # $http_origin動態獲取請求客戶端請求的域 不用*的緣由是帶cookie的請求不支持*號 add_header Access-Control-Allow-Origin $http_origin; # 表示請求頭的字段 動態獲取 add_header Access-Control-Allow-Headers $http_access_control_request_headers; # OPTIONS預檢命令,預檢命令經過時才發送請求 # 檢查請求的類型是否是預檢命令 if ($request_method = OPTIONS){ return 200; } } }
發送預檢命令的是非簡單請求,具體能夠看慕課網ajax跨域徹底講解
實際上不是非簡單請求的且不帶cookie只需2個字段便可解決跨域
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Allow-Origin $http_origin;
這時只需改ajax請求的端口接口,無需修改前端服務器的地址
最後附上源碼:
nginx解決跨域問題