同源策略 跨域
关于同源策略
同源指的是: 协议 , 域名 , 端口 三个完全相同。只有浏览器有同源策略。
同源策略的作用: 为了用户数据的安全,防止恶意窃取用户数据。如果没有同源策略,浏览器会变得很不安全。
当不同源的时候,也就是协议 或 域名 或 端口 不一样的时候,去请求数据就会产生跨域。
同源策略的本质
其实跨域的时候是可以发送ajax请求的,而且请求是成功的,返回的结果也拿了回来,但是浏览器不让用,会报跨域错误。
浏览器不让用?(用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语句
客户端动态创建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>
还会更新。。。。。木有写完