跨域问题梳理

跨域问题是由浏览器的同源策略限制引起,

浏览器的同源策略是为了保证我们网站的安全。

场景示例:

www.A.com 简称A服务

www.B.com 简称B服务

跨域分两个场景:

场景1.

浏览器打开A服务网站,在A网站所在的浏览器页面内打开B网站的页面(ifram可以做到,没详细了解)

有些html标签是允许跨域的,

1、<img src=xxx>
2、<link href=xxx>
3、<script src=xxx>

这是一种前端页面跨域跨域;

场景2.

浏览器打开A服务的网站,在A网站内因为业务需要,需要用js请求B服务的接口取数据。

这是一种前端请求后端接口跨域

解决办法:

  • 前端代理(Angular自带)
  • Nginx反向代理
  • A服务网关转发
  • CORS (后端接口给response的Header设置Access-Control-Allow-Origin)
  • JSONP
前端代理:

没有了解

nginx反向代理:

将所有涉及到B请求url都在nginx做代理转发配置,这样前端涉及到B的请求都改为请求nginx,

注意:A服务的所有接口也要由nginx代理,这样就能保证前端所有的请求都是请求nginx这一个地址与端口,当然用的传输层协议就一样了,

A服务网关转发:

如果A服务有网关服务,可以在网关服务配置转发处理,所有关于B服务接口的请求都由A服务的网关转发请求(后端服务之间不存在跨域问题,跨域时浏览器的限制)

CORS

CORS是一个W3C标准,全称是跨域资源共享(Cross-origin resource sharing)

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

JSONP

JOSNP允许页面接受另一个域的JSON数据,通过在页面增加一个可以从其它域加载带有回调的JSON响应的

模拟使用CORS解决跨域场景:

在csdn网页的控制台里的console里,请求本地启动的后端:fetch('http://localhost:9000/gw/get1')

浏览器console报错:

浏览器network报错:

对于这样的报错,需要后端接口返回 response的Header 添加Access-Control-Allow-Origin

分析:这是一个权限控制,用于授权允许访问当前服务的别的服务的地址,

比如B服务的一个接口允许所有别的服务的js跨域请求这个接口,就设置*;如果只允许A服务的js跨域请求这个接口,就将设置www.A.com,设置这些内容是给浏览器用的,浏览器接受到接口的响应数据之后会判断response的Header里有没有Access-Control-Allow-Origin,以及Access-Control-Allow-Origin的值是什么,如果存在且当前请求满足设置的值就正常接受接口的值,如果 不存在或者设置的值不包含当前请求发起者的域名,则浏览器直接扔掉响应数据。

示例:

response.setHeader("Access-Control-Allow-Origin", "*");//允许所有的源请求

//允许指定的源请求(这里允许),这里设置允许源是csdn,则在csdn控制台请求这个接口可以,在知乎的控制台请求这个接口就不行

response.setHeader("Access-Control-Allow-Origin", "CSDN博客 - 专业IT技术发表平台");

后端代码:

@GetMapping("/get1")
public void get1(HttpServletRequest request, HttpServletResponse response) throws IOException {
    PrintWriter writer = response.getWriter();
    writer.write("no cors");
}

@GetMapping("/get11")
public void get11(HttpServletRequest request, HttpServletResponse response) throws IOException {
    PrintWriter writer = response.getWriter();
    writer.write("cors ok");
    response.setHeader("Access-Control-Allow-Origin", "*");//允许所有的源请求
}
@GetMapping("/get111")
public void get111(HttpServletRequest request, HttpServletResponse response) throws IOException {
    PrintWriter writer = response.getWriter();
    writer.write("cors ok");
    //允许指定的源请求,在csdn控制台可以,在知乎的控制台就不行
    response.setHeader("Access-Control-Allow-Origin", "https://blog.csdn.net");
}

在浏览器打开csdn,打开控制台的console,执行:fetch('http://localhost:9000/gw/get11',{mode:'cors'})

可以正常请求接口:

后记:在实际业务场景里,如果我们需要访问别的系统的接口,可以让别的系统配置接口放行解决,其实就是别的系统做了一个拦截器,在拦截器里对配置放行接口的response设置Access-Control-Allow-Origin

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值