轻松解决跨域问题

跨域:

官方解释:跨域是指浏览器不能执行其他网站的脚本。它是有浏览器的同源策略造成的,是浏览器施加的安全限制。

从这里面我们可以提取到第一个点-->“跨域问题是浏览器产生的”
复制代码

跨域,又称跨域名访问。其中又分为:二级域名跨域、多级 域名跨域、端口号跨域以及协议跨域。

下面说明这几种跨域,假如一网站是 http://www.abc.com,那么该网站访问其他资源的路径可能是以下几种:

1、http://abc.com         二级域名跨域
2、http://www.abc.cn      主域名跨域
3、http://www.def.com     主域名跨域
4、https://www.abc.com    协议跨域复制代码

解决跨域的方法:

一、jsonp 跨域

jsonp跨域是利用,在浏览器当中,img标签的src、以及script标签的src、以及link标签的href不受浏览器同源政策的限制。绕过ajax去请求数据。既然如此,我们就可以利用动态的创建script标签的方式,去跨域请求数据了。

这里我使用node做示例,那么我就利用express来建立一个jsonp数据,之后就来请求这个数据即可

app.get('/jsonp', (req, res, next) => {
    res.jsonp({
        data: 'this is a jsonp data'
    })
})复制代码

既然jsonp是利用script标签去请求数据,那么我们就需要动态创建script标签

第一步:定义处理函数,用来处理接收到的数据

function getData(res) {
    console.log(res)
}复制代码

第二步:创建script标签,去请求数据

let jsonp = document.createElement('script')
jsonp.src = 'http://localhost:3000/jsonp?callback=getData'复制代码

这里jsonp默认使用callback作为请求参数

在这之后数据会被打印出来。

jsonp的优势:兼容性比较好(几乎所有浏览器都支持script标签)

jsonp的劣势:jsonp只支持get请求

二、cors跨域

CORS需要浏览器和服务器同时支持,目前几乎所有浏览器都支持CORS,IE不能低于IE10。整个CORS跨域的过程,前端都是浏览器自动完成的,浏览器一旦发现ajax请求跨域资源,就会自动添加一些附加的头信息,有时还会多一次试探性的OPTIONS请求。

CORS又分为简单请求和非简单请求

① 简单请求:

要同时满足以下几个条件:

1、请求方式是   HEAD、GET、POST其中的一个

2、http的请求头不超出以下几种信息:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type

3、Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

简单请求时浏览器会自动带上一个请求头" Origin: 客户端域名 ”

当浏览器接收到服务器返回的响应时,会对响应头进行分析。如果 存在 Access-Control-Allow-Origin:“客户端域名”;那么浏览器就会把请求到的数据返回给ajax对象,否则就会触发ajax的onerror事件,抛出一个错误异常

② 非简单请求

对于非简单请求一般分为以下步骤

第一步:

浏览器先发出一个options的请求。并且包含一些头部信息:

Origin:客户端域名Access-Control-Request-Headers: content-type (表明客户端发送的请求头数据)Access-Control-Request-Method: POST (表明客户端发送的请求类型)复制代码

第二步:

服务器返回options请求

Access-Control-Allow-Origin:允许跨域的域名(可以是指定域名,也可以是全域名“*”)Access-Control-Allow-Headers: “与客户端对应”Access-Control-Allow-Method: 与客户端的对应或者大于客户端复制代码

第三步:

客户端检查options请求的响应头。如

Access-Control-Allow-Origin:允许跨域的域名Access-Control-Allow-Headers: “与客户端对应”Access-Control-Allow-Method: 与客户端的对应或者大于客户端复制代码

如果服务器的响应头与浏览器的请求头对应了,浏览器会正式发出请求,服务器对请求做出响应,并带上之前的请求头完成跨域。

不过虽然上面的 对响应头的设置已经可以实现跨域了不过会造成session的丢失,对此我们需要设置另一个请求头参数Access-Control-Allow-Credentials = true,在默认false情况下客户端是不会携带cookies到服务器的。

session丢失的解决:

在响应头里边,指定唯一的允许跨域的域名。服务端在响应头里边。指定Access-Control-Allow-Credentials:true,以及客户端的ajax对象,必须指withCredentials: true;

更好的了解cors跨域的同学可以看看阮一峰老师的《跨域资源共享 CORS 详解

下面是express实现cors跨域,浏览器端的请求头浏览器会自动添加

router.options('/getCorsData',(req,res)=>{
    res.header('Access-Control-Allow-Origin','*')   //设置允许访问的域名 * 代表所有
    res.header('Access-Control-Allow-Headers','content-type')
    res.header('Access-Control-Allow-Method','OPTIONS,POST,PUT')    
    res.header('Access-Control-Allow-Credentials','true')
    res.send(200)
})
复制代码

三、代理跨域

代理跨域的道理很简单,既然跨域是因为浏览器的同源策略引起的,那么非同源资源不交给浏览器去直接请求,而是让同源服务器去请求再返回给浏览器


express代码示例:

app.get('/getdata', (req, res) => {
    request('http://localhost:3000/getCors', (err, response, body) => {
        res.json(response)
    })
})复制代码

以上代码是我是开了两个服务器模拟的一个 3001 端口另一个是3000端口,属于端口跨域,在3001的页面中去访问getdata时服务器向3000端口请求数据,并把数据返回给页面,完成跨域。

但一般我们都是去使用中间件去完成代理跨域。比如 http-proxy-middleware,有兴趣的可以去github中查看使用方法。

总结

知识在于积累,生命在于折腾,有错误的请留言指出,批评使我进步


转载于:https://juejin.im/post/5baa196be51d450e4f38c603

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值