跨域
什么是跨域?
跨域就是指浏览器不能执行其他网站的脚本。这是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制
浏览器为了用户的信息安全,网页中有一个网络请求技术:AJAX 在网络请求时 请求的网址 和当前页面的网址不是同一台服务器就会被拒绝接受服务器发送的数据
例如:a页面想获取b页面资源,如果a、b页面的协议或域名或端口或子域名不同,只要有其中一项不同,那么所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源
注意:跨域限制访问,其实是浏览器的限制,这一点很重要
什么是同源策略?
同源策略:指协议,域名(ip),端口(port)三者都要相同代表同源,只要有其中一个不同就会产生跨域
注意:网址中的pathname参数并不参与同源判断
例如:
同源
https://www.baidu.com/index.html
https://www.baidu.com/home
异源(协议不一样)
http://www.baidu.com/index.html
https://www.baidu.com/ajax
异源(端口(port)不一样)
http://www.baidu.com/index.html
http://www.baidu.cn/ajax
异源(域名(IP)不一样)
http://www.baidu.com/index.html
http://www.sina.com/index.html
同源
这个虽然看着似乎不一样,但是经过DNS解析后,域名和IP就是一样的,所以也是同源的
端口号随便写的
baidu的DNS解析为 119.75.217.109:8080
http://www.baidu.com/index.html
http://119.75.217.109:8080/ajax
如何解决Ajax跨域问题?
我们只需要在头部加一行下列的代码,即可解决这个问题
res.setHeader("Access-Control-Allow-Origin","*")
router是自己封装的一个函数,用来做网络请求读取文件的,没有封装这种类似功能的函数就需要自己先去写一下,http网络请求,fs模块读取文件
实例
var router=require("./router.js")
router.get("/ajax1",function(req,res){
res.setHeader("Access-Control-Allow-Origin","*")
res.end('{"name":"karen",age:20}')
})
<body>
<h1>成都</h1>
<button onclick="fn()">跨域ajax请求</button>
<script>
function fn(){
var xhr=new XMLHttpRequest()
xhr.open("get","http://192.168.43.132:8080/ajax1")
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText)
}
}
}
</script>
</body>
什么是JSONP?
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题
由于同源策略,一般来说位于非同一服务器的的网页是无法相互沟通的,而 HTML 的<script>
元素是一个例外
利用 <script>
元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是 JSONP
用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析
虽然用script标签的src属性去请求跨域服务器的网址 不会报跨域错误,但是会直接把请求过来的编码用v8引擎去运行
因此我们可以在后端写一个js引擎能识别的字符串发送给前端,这个字符串是这样的:’ fn({“name”:“karen”}) ',前端可以用script标签的src属性去请求这个网址,请求完毕以后 v8就会直接运行这个编码 去调用fn函数,所以我们必须提前创建这个函数
而关于函数的名称问题: 前端可以通过querystring把函数名以参数的形式发送给后端,后端将发送过来的网址解析了以后库直接拼接到数据中去
实例
<body>
<button onclick="fn2()">jsonp请数据</button>
<script>
function fn2(){
var name="data"
window[name]=function(arg){
console.log(arg)
}
var script1=document.createElement("script")
script1.src=`https://api.weibo.com/2/statuses/home_timeline.json?access_token=2.00ZmCkcDlel8HDd856f9b9ccsVwsYD&callback=${name}`
document.body.append(script1)
}
</script>
什么是Proxy
Proxy就是指代理软件或代理服务器,也可以认为是一种网络访问方式
代理类,用来进行事物不想或不能进行的其他操作,比如当你对数据库进行操作时,代理可以在你对数据库操作完后,记录下你所进行的操作
Proxy 代理服务:后端合法的去请求别的后端(oAuth授权-token) 再发给前端 前端写成自己的页面
实例
下面的一个案例是去请求百度的首页数据,请求到后直接返回给前端,因为请求的是一个html页面,所以返回回来的页面浏览器也能直接解析,我们就可以直接看到一个跟百度首页一模一样的页面啦
router.get("/home",function(req,res){
request("http://www.baidu.com/index.html",function(agr1,arg2,arg3){
res.end(arg3)
})
})