跨域解决方案

跨域及其解决方案

1. 跨域是什么

​ 跨域(cross domain request):是指一个域下的文档或脚本试图去请求另一个域下的资源,二者所在的请求地址不同,域名不同、端口号不同、请求协议不同

​ 举个栗子:

`http://www.123.com/index.html 调用 http://www.123.com/server.PHP (非跨域)`
`http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)`
`http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)`
`http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)`
`http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)`

​ 请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

​ 跨域是由前端浏览器的同源策略造成的,是浏览器对js施加的安全限制。浏览器不会阻止你向另一个域名发送请求,请求可以发出,但是你拿不到响应的结果。

2. 如果没有同源限制两点危险场景

2.1 没有同源策略限制的接口请求

​ cookie的存在的目的是让服务端知道谁发出的这次请求,如果你请求了接口进行登录,服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中,服务端就能知道这个用户已经登录过了。

若没有同源策略限制的接口请求,就会出现传说中的CSRF攻击,如下图所示:

在这里插入图片描述

2.2 没有同源策略限制的Dom查询

​ 1.有一天你刚睡醒,收到一封邮件,说是你的银行账号有风险,赶紧点进www.yinghang.com改密码。你吓尿了,赶紧点进去,还是熟悉的银行登录界面,你果断输入你的账号密码,登录进去看看钱有没有少了。
​ 2.睡眼朦胧的你没看清楚,平时访问的银行网站是www.yinhang.com,而现在访问的是www.yinghang.com,这个钓鱼网站做了什么呢?

// HTML
<iframe name="yinhang" src="www.yinhang.com"></iframe>
// JS
// 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom
const iframe = window.frames['yinhang']
const node = iframe.document.getElementById('你输入账号密码的Input')
console.log(`拿到了这个${node},我还拿不到你刚刚输入的账号密码吗`)

3.同源策略限制

​ 同源策略限制以下几种行为:

		1.) Cookie、LocalStorage 和 IndexDB 无法读取 

​		2.) DOM 和 Js对象无法获得

​	 	3.) AJAX 请求不能发送

​ 这里要注意的是,只有访问类型为xhr(XMLHttpRequest)的才会出现跨域。

4.跨域解决方案有哪些

4.1 前端来处理跨域问题

4.1.1 JSONP

​ 在HTML标签里,一些标签比如script、img这样的获取资源的标签是没有跨域限制的,利用这一点,我们可以这样干:

 getJson () {
      let url = 'http://10.4.139.133:18080/crossDomain/hello'
      this.$jsonp(url, {
        params: {},
        jsonp: 'jsonpCallback'
      })
        .then((json) => {
          // 返回的jsonp数据不会放这里,而是在 window.jsonpCallback
          console.log(json)
        })
    }

jsonp的缺点:只能发送get一种请求。

2)http-proxy-middleware 代理解决(项目使用vue-cli脚手架搭建)(开发时配置)

devServer: {
        open: true,
        port: 8080,
        proxy: {
          '/api': {      
            target: 'http://10.4.139.133:18080',
            changeOrigin: true,
            pathRewrite: {
              '^/api': '/'
            }
          },
        }
    },

4.2 后端处理跨域问题

4.2.1 CORS(跨域资源共享)(cross-origin resourse sharing)

​ 浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。通过服务器的response响应头里参数设置 Access-Control-Allow-Origin 就可以开启 CORS。前端无须设置,若要带cookie请求:前后端都需要设置

方法一:过滤器

response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET,PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Origin","*");// 允许访问的域(协议+域名+端口)
        response.setHeader("Access-Control-Allow-Credentials", "true"); // 后端允许发送Cookie
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token,access-control-allow-origin");

方式二:@crossorigin跨域

    @ResponseBody
    @CrossOrigin
    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello(HttpServletResponse rsp){
        return "jsonpCallback";
    }
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)可以写参数

4.2.2 服务器代理

​ 跨域是js的特性,服务端不受影响,所以可以用服务器来请求对应的数据,再返给前端.

nginx反向代理

    server {
            listen          80;
            server_name     10.4.139.32;
            
            location / {
                    root   /usr/share/nginx/html/dist;
                    index  index.html index.htm;
            }
            location /api/ {
                    proxy_pass http://10.4.139.133:18080/;
            }             
    }

总结:一般采用cors或nginx代理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值