一個域名下的網站向另外一個域名下的網站請求資源(靜態文件)css
好比: 引用別的網站的css link 標籤 引入別的網站的js 文件,可是 瀏覽器有同源策略.有的人會問? 同源策略是啥?html
所謂同源(即指在同一個域)就是兩個頁面具備相同的協議(protocol),主機(host)和端口號(port)前端
瀏覽器規定ajax請求只能使用來自於本身網站的數據,不容許使用本身網站之外的數據。
(1). 瀏覽器容許ajax向其它網站發送請求
(2). 瀏覽器也容許ajax接收其它網站的響應
(3). 可是瀏覽器會檢查響應數據的來源(origin):
a. 若是數據來源的服務器地址和當前網頁所在的地址相同,才能使用數據
b. 若是數據來源的服務器地址和當前網頁所在的地址不一樣,就不容許使用數據 -----同源策略 (cross orgin resoures shareing)node
下面這些狀況都屬於跨域,請牢記.jquery
(1). http://www.a.com -> http://www.b.com **域名不一樣** (2). http://oa.tedu.com -> http://hr.tedu.com **子域名不一樣** (3). http://localhost:3000 -> http://localhost:8080 **端口號不一樣** (4). http://12306.cn -> https://12306.cn **協議不一樣**
特別提示: 若是你是在一臺電腦上進行跨域測試的話 localhost 和127.0.0.1 這就能夠實現跨域操做了.ajax
1.若是你的後端是node.js 開發的話 安裝expres中間件cors
(1). 項目本地安裝cors模塊: npm i -save cors
(2)npm
app.use(cors({ origin:['http://localhost:8080', "http://127.0.0.1:5500"], credentials:true }))
2.服務端CORS跨域: 讓服務器端在返回數據前,修改響應頭中的來源json
地址與前端服務器地址同樣。
服務端接口返回數據時,不要用res.send(result) 由於 res.send()裏面封裝好了瀏覽器的源頭.
應該:後端
res.writeHead(200,{ "Access-Control-Allow-Origin":"http://127.0.0.1:5500" //和前端項目所在服務器的地址保持一致 }); res.write(JSON.stringify(result)); res.end();
不過這個方法的缺點就是你每一個路由都要修改響應頭信息.跨域
Jsonp(JSON with Padding) 是 json 的一種"使用模式",可讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。
既然ajax不能夠發起跨域請求 可是標籤能夠 script的屬性 src="" 能夠實現跨域的請求 可是咱們如何 把這個數據接收到呢?
首先看下服務器端的代碼 ,我用的是node.js 中http 模塊 和url 模塊
const http=require("http"); // 引入bodyparse 中間件 const url=require("url") // 建立服務器 http.createServer((req,res)=>{ var weather="北京 晴 4-24" res.writeHead(200,{ "Content-Type":"text/plain; charset=utf-8" }) // jqery 用callback var fname=url.parse(req.url,true).query.callback var stmt =`${fname}("${weather}")` res.write(stmt) res.end() }).listen(8080) // 解析url 對象
瀏覽器代碼 要用到jquery 將數據類型改成"jsonp" 你會發現已經實現了跨域請求.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="jquery-1.11.3.js"></script> </head> <body> <button>今日天氣</button> // <!-- <script src="http://localhost:8080?fname=show"></script> --> </body> <script> $("button").click(function(){ // $(` <script src="http://localhost:8080?fname=show">`) // .appendTo("body") $.ajax({ url:"http://localhost:8080", type:"get", dataType:"jsonp", success:function(result){ console.log(result) } }) }) // function show(data){ // alert(data) // } </script> </html>
不少人都很好奇,$ajax()不是不能夠跨域? 若是你只看表面那就錯了,
接下來和你們探討下底層原理.
****首先ajax是絕對不能進行跨域,爲啥 jquery 實現了呢, 那是jquery dataType:"jsonp"的 裏面封裝的是這樣的一個函數這就是原理.
$(` <script src="http://localhost:8080?fname=show">`) .appendTo("body") //在頁面建立一個函數 這個函數的做用 對應的是 function show(data){ $("body>script:last").remove() alert(data) }
這句話啥意思呢就是,點擊按鈕建立一個script 並加到body 標籤的最後,並在全局下建立一個函數 這個函數的做用呢:
**// 服務端 返回的其實一個函數調用語句 show()** 調用以後,並刪除<script>標籤. 點擊按鈕 調用函數 ,調用完script 標籤 並刪除他,防止頁面中多餘的script 的標籤.