跨域、同源策略

同源策略

同源

  • 同协议
  • 同域名
  • 同端口
    当页面上有ajax请求时,浏览器比较当前ajax请求和当前页面的url,接口,协议,域名,端口 是否完全一致,如果不一致,浏览器会拒绝掉.
    在这里插入图片描述

那么为啥要同源呢?

为了保护知识产权,不然你做的接口别人网站都随便用了

拒绝是服务器拒绝还是浏览器拒绝呢

是浏览器拒绝的

如果跨域请求第三方接口,或者把自己的接口提供给第三方,要如何做呢?

一般有三种方法,哪三种方法呢???是下面三种方法:

  • JSONP
  • CORS
  • 服务器中转
    就这三种

JSONP

原理

  • 同源策略只限制ajax请求,不限制script标签加载js.可以同script标签请求加载资源,并提前写好接收函数.
  function handleData(data){
    console.log(data)
  }
</script>
  
<script src='http://xxx.xxx.com/xxx?callback=handleData'>//把callback=handleData发给服务器,服务器拿到handleData
  • 服务器接到请求后,从callback参数获得handleData,然后把原始数据处理后变成handleData({a: 1})
  • 服务器返回handleData({a: 1})后等于执行这个函数,因为handleData函数已经设定过

举例

  • 先用nodejs写个服务器,让那个服务器在接到请求后返回fn(data)
const http = require('http')
const url = require('url')
http.createServer((req,res) =>{
  let urlObj = url.parse(req.url,true)
  if(urlObj.pathname === '/getWeather'){
    let data = {weather: '晴',city: '杭州'}
    res.end(`${urlObj.query.callback}(${JSON.stringify(data)})`)//callback就是=后面的fn,因此服务器返回fn(data),浏览器接收到后就会根据预置的方法运行
  }else{
    res.writeHead(404,'not fond')
    res.end('not fond')
  }
}).listen(8888)//端口8888,终端node一下打开服务器
  • 浏览器html页面这么写
  <script>
    function fn(data){
      document.querySelector('p').innerText = data.weather
    }
  </script>
  //发送请求,callback里的fn传给服务器,服务器拿到再返回给浏览器fn(),浏览器然后执行
  <script src='http://127.0.0.1:8888/getWeather?callback=fn'></script>

如果遇到多个请求太麻烦,可以封装一下

function jsonp(url,data={}){//确定形参为url和服务器传送内容data,默认为空对象{}
//使用promise,先获得data数据,再执行函数
return new Promise((resolve,reject) =>{
  window.fn = data => resolve(data)//1.函数要绑定要全局上 2.之后设置then()中怎么执行data 3.当调用这个全局函数fn时,resolve出data给被人用
  let script = document.createElement('script')//创建script的标签
  let query = Object.entries(data).map(a=>`${a[0]}=${a[1]}`).join('&')
  script.src = url+'?callback=fn&'+query//在script标签上添加链接
  script.onerror = () =>reject('加载失败')
  document.head.appendChild(script)//添加script标签
  document.head.removeChild(script)//删除script标签
})
}

CORS

原理

  • 发送Ajax请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin。后台收到请求后,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断该响应头中是否包含当前Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果没有浏览器直接驳回。
  • 一般都是些公开的api可以

前端需要做什么

  • 什么都不需要做

服务端需要做什么

  • 加一个Access-Control-Allow-Origin响应头

res.setHeader('Access-Control-Allow-Origin','*')

服务器说:“浏览器兄弟,我允许任何域都能获取资源,你不用替我拦截非同源的请求了了”

JSONP和CORS都需要服务器配合,如果不配合怎么办

这时候就用到服务器中转

服务器中转

  • 发给我服务器
  • 我的服务器再发给目标服务器
  • 目标服务器返回我的服务器
  • 我的服务器再返回
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值