同源指的是: 協議 , 域名 , 端口 三個徹底相同。只有瀏覽器有同源策略。html
同源策略的做用: 爲了用戶數據的安全,防止惡意竊取用戶數據。若是沒有同源策略,瀏覽器會變得很不安全。前端
當不一樣源的時候,也就是協議 或 域名 或 端口 不同的時候,去請求數據就會產生跨域。node
同源策略的本質ajax
其實跨域的時候是能夠發送ajax請求的,並且請求是成功的,返回的結果也拿了回來,可是瀏覽器不讓用,會報跨域錯誤。json
瀏覽器不讓用?(用ajax請求返回的數據中帶着響應頭,響應頭中記錄着數據來源的ip地址,可是當前瀏覽器地址欄中的ip地址與響應頭中的ip地址不一樣,因此瀏覽器不讓用)跨域
解決辦法? cors瀏覽器
在服務端配置響應頭: 將返回結果中的響應頭的ip地址 和 當前網頁中的ip地址 設置成一致的,就可解決 安全
//在node.js中的解決方法 這樣寫每一個返回的數據都要改 res.writeHead(200,{//只修改了一個 "Access-Control-Allow-Origin":"客戶端網頁地址", // 將這裏的網址寫爲 當前網頁的地址
"Content-Type":"application/json;charset=utf-8" //內容類型,返回json });
res.write(JSON.stringify(result));
res.end();
//在app.js中,使用中間件的方式, 提早改好, 一勞永逸 const cors = require("cors"); //引入cors模塊,用來實現跨域 server.use(cors({ origin:["http://127.0.0.1:8080", //將返回結果的響應頭中的ip地址修改成 和當前網頁的地址一致 "http://localhost:8080"],//大括號中寫的是當前網頁的地址 credentials:true //容許接收客戶端帶來的身份信息 }))
jsonp解決跨域服務器
jsonp原理?:客戶端動態建立script ,藉助script發送跨域請求, 服務器端將要返回的數據填充進 js語句裏返回,script收到js語句後執行js語句app
客戶端動態建立script標籤,藉助script標籤發送跨域請求,服務器端返回一個函數調用,將數據填充到函數調用中
jsonp不支持post請求
01 利用了script標籤能夠跨域請求的特性,不受同源策略的限制
02後臺返回一個 函數調用
ajax和jsonp的關係???
它們沒有任何關係
jsonp只能經過 get 方式請求
dataType:'jsonp' ,實際上是動態建立<script>, 藉助<script>發送跨域請求,必須有服務器的支持
全名JSON with PADDING 填充式JSON
方案一: 用<scritp src="服務端接口地址"代替$.ajax發送請求" ></script>
服務端:將要發送的數據填充在一條js語句中 res.write( `document.write('${day}')`)
客戶端:<script src="服務端接口地址"></script>,發送請求到服務端,並能接受到服務端返回的js語句字符串。
script只要收到 js語句,就會馬上自動執行
問題:要在客戶端執行的語句,在服務端寫死了,重口難調
代碼以下:
1 //服務器 2 //引入支持接收請求,返回響應的模塊http 3 const http=require("http") 4 //建立服務器程序實例 5 http.createServer( 6 //每當有客戶端發來請求時,自動調用一下回調函數 7 (req,res)=>{ 8 var day='北京 晴 18~32度' 9 10 res.writeHead(200,{//可選,將字轉爲utf-8格式 未來ajax自帶utf轉碼 11 "Content-Type":"text/plain; charset=utf-8" 12 }) 13 14 res.write( `document.write('${day}')`) 15 res.end(); 16 } 17 ).listen(8888)
<!-- 客戶端 --> <!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> </head> <body> <script src="http://localhost:8888"> </script> <!-- 向服務器發送請求,並接收數據,這個數據要:js語句 --> </body> </html>
方案二:提早在客戶端定義一個函數,用於處理服務端返回的請求,服務端僅使用函數名拼接一條函數調用的js語句
客戶端: function show (day){ // 客戶端定義一個函數
任意js語句
}
客戶端利用scrtpt發送請求,並接收 服務器端 發回來的參數( `show('${day}')`)
服務端: res.write( `show('${day}')`) // 服務器拼接一個js調用語句 show()
問題: 本該定義在客戶端的函數名,在服務端是寫死的,重口難調
代碼以下
1 //服務器 2 //引入支持接收請求,返回響應的模塊http 3 const http=require("http") 4 //建立服務器程序實例 5 http.createServer( 6 //每當有客戶端發來請求時,自動調用一下回調函數 7 (req,res)=>{ 8 var day='北京 晴 18~32度' 9 10 res.writeHead(200,{//可選,將字轉爲utf-8格式 未來ajax自帶utf轉碼 11 "Content-Type":"text/plain; charset=utf-8" 12 }) 13 14 res.write( `show('${day}')`) 15 res.end(); 16 } 17 ).listen(8888)
1 <!-- 客戶端 --> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>Document</title> 9 </head> 10 <body> 11 12 <script> 13 var show=(day)=>{ 14 // document.write(day) 15 alert(day) 16 } 17 18 </script> 19 20 21 22 <script src="http://localhost:8888"> </script> <!-- 向服務器發送請求,並接收數據,這個數據要:js語句 --> 23 <!-- script向服務端請求回來的數據是 `show('${day}')` --> 24 25 </body> 26 </html>
還會更新。。。。。木有寫完