什么是跨域?跨域解决方法

同源策略是浏览器的安全特性,限制了不同源之间的交互,导致跨域问题。跨域表现为协议、域名或端口不同。非同源限制包括无法读取Cookie、DOM操作和AJAX请求。解决跨域的方法有JSONP(仅支持GET)、CORS(需服务器配合,支持带Cookie的跨域)和通过Nginx代理。JSONP简单但不支持POST,CORS是标准解决方案,Nginx代理则提供了一种配置方式。
摘要由CSDN通过智能技术生成

一、为什么会出现跨域问题

        跨域: 浏览器通常用于在同一个域下发起 HTTP 请求,但出于安全考虑,现代浏览器实施了同源策略(Same-origin policy)限制了从一个源加载的文档或脚本如何与另一个源的资源进行交互。

        同源策略:是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。同源就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。如果尝试不同源(不同的域、协议或端口)中请求资源,会遇到跨域问题。

二、什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

当前页面url

被请求页面url

是否跨域

原因

http://www.test.com/

http://www.test.com/index.html

同源(协议、域名、端口号相同)

http://www.test.com/

https://www.test.com/index.html

跨域

协议不同(http/https)

http://www.test.com/

http://www.baidu.com/

跨域

主域名不同(test/baidu)

http://www.test.com/

http://blog.test.com/

跨域

子域名不同(www/blog)

http://www.test.com:8080/

http://www.test.com:7001/

跨域

端口号不同(8080/7001)

三、非同源限制

【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

【2】无法接触非同源网页的 DOM

【3】无法向非同源地址发送 AJAX 请求

四、跨域解决方法

【1】JSONP

       JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

$.ajax({
    url: 'http://www.test.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "handleCallback",    // 自定义回调函数名
    data: {}
});

【2】跨域资源共享(CORS)

       CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

       a.普通跨域请求:只需服务器端设置Access-Control-Allow-Origin,响应头中添加合适的 CORS 策略,允许特定的外部域访问资源。

      b.带cookie跨域请求:前后端都需要进行设置

    【服务端设置】

        编写filter在response对象中添加响应头,告诉浏览器允许跨域访问,* 号代码允许所有的请求域名,所有的请求方法跨域访问

//告诉浏览器允许所有的域访问
//注意 * 不能满足带有cookie的访问,Origin 必须是全匹配
//resp.addHeader("Access-Control-Allow-Origin", "*");
//解决办法通过获取Origin请求头来动态设置
String origin = request.getHeader("Origin");
if (StringUtils.hasText(origin)) {
    resp.addHeader("Access-Control-Allow-Origin", origin);
}
//允许带有cookie访问
resp.addHeader("Access-Control-Allow-Credentials", "true");
//告诉浏览器允许跨域访问的方法
resp.addHeader("Access-Control-Allow-Methods", "*");
//告诉浏览器允许带有Content-Type,header1,header2头的请求访问
//resp.addHeader("Access-Control-Allow-Headers", "Content-Type,header1,header2");
//设置支持所有的自定义请求头
String headers = request.getHeader("Access-Control-Request-Headers");
if (StringUtils.hasText(headers)){
    resp.addHeader("Access-Control-Allow-Headers", headers);
}
//告诉浏览器缓存OPTIONS预检请求1小时,避免非简单请求每次发送预检请求,提升性能
resp.addHeader("Access-Control-Max-Age", "3600");

 【前端设置】根据xhr.withCredentials字段判断是否带有cookie         

$.ajax({
   url: 'http://www.test.com:8080/login',
   type: 'get',
   data: {},
   xhrFields: {
       withCredentials: true    // 前端设置是否带cookie
   },
   crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
});
 
 

【3】代理服务器(ngnix等) 

        在服务器端设置一个代理,所有前端请求首先发送到代理服务器,由代理服务器转发请求到目标服务器,然后再将响应返回给前端。

         a. 通过nginx代理配置可以解决跨域

参考:什么是跨域?跨域解决方法

前端解决跨域的九种方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值