跨域简介
跨域 也就是 非同源策略请求
那么同源策略请求有 ajax、fetch
如果 区分 是否会跨域
需要 协议,域名,端口号一致就是同源,只有有一个不同就是跨域
1. 修改hosts文件
2. Jsonp
首先需要了解 script img link lframe 不存在跨域请求的限制 例如 cdn
第一步 在 客户端使用script标签 发送一个路径去访问服务端,这个路径后面写参数用?拼接 callback=func(),向服务器发请求,同时会把本地的一个函数传递给服务器,服务器接收到客户端的请求后,准备数据,通过相应给客户端返回数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ED3SLf7C-1628500468834)(D:\wulianwangsanban\狂神笔记\魏传宝图片S\面试题\image-20210803111205857.png)]
$.ajax({
url:“http://127.0.0.1:8080/list”
dataType:“jsonp”//执行的是jsonp请求
})
问题
- Jsonp只能发送 get请求 不安全
3.CORS跨域资源共享
//处理简单请求Access-Control-Allow-Origin
response.setHeader(“Access-Control-Allow-Origin”, “*”);
**//处理非简单请求 有 预检的 options请求
response.setHeader(“Access-Control-Allow-Methods”, “POST,GET,PUT,DELETE,PATCH,OPTION”);
response.setHeader(“Access-Control-Allow-Headers”, “Content-Type,Access-Token”);
问题
如果要发送json的话 需要"Access-Control-Allow-Origin"设为指定的域名 ,如果 是*的话会失败
解释
[Web漏洞 | CORS跨域资源共享漏洞 - 云+社区 - 腾讯云 (tencent.com)](https://cloud.tencent.com/developer/article/1601688#:~:text=跨域资源共享 (CORS)是一种放宽同源策略的机制,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制,以使不同的网站可以跨域获取数据。. 我们先来简单分析一下CORS跨域获取资源的过程:. CORS定义了两种跨域请求: 简单请求,和 非简单请求 。. 简单跨域请求就是使用设定的请求方式请求数据,而非简单跨域请求则是在使用设定的请求方式请求数据之前,先发送一个OPTIONS预检请求,验证请求源是否为服务端允许源。. 只有"预检"通过后才会再发送一次请求用于数据传输。. 当我们需要发送一个跨域请求的时候,浏览器会首先检查这个请求,如果它是简单跨域请求,浏览器就会立刻发送这个请求。.)
ssm中设置在拦截器中 只能放在拦截器 第一个
package com.Handler;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @auther WeiChuanBao
* @date 2021/8/3 9:50
*/
public class AllHandler implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//处理简单请求Access-Control-Allow-Origin
response.setHeader("Access-Control-Allow-Origin", "*");
/**
* *******************请求***************************
* Access-Control-Request-Headers: content-type
* Access-Control-Request-Method: POST
* Origin: http://localhost:8080
* Origin: 在CORS中专门作为Origin信息供后端比对,表明来源域。
* Access-Control-Request-Method: 接下来请求的方法,例如PUT、DELETE等等
* Access-Control-Request-Headers: 自定义的头部,所有用setRequestHeader方法设置的头部都将会以逗号隔开的形式包含在这个头中
* *******************相应***************************
* 然后如果服务器配置了CORS,会返回对应对的字段,具体字段含义在返回结果是一并解释。
* Access-Control-Allow-Origin: 允许进行跨域请求的域名
* Access-Control-Allow-Methods: 允许进行跨域请求的方式
* Access-Control-Allow-Headers: 允许进行跨区请求的头部
*/
response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,PATCH,OPTION");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
response.setHeader("Access-Control-Max-Age", "7*60");
/**
* Access-Control-Allow-Credentials: 是否允许请求带有验证信息
* Access-Control-Max-Age: 缓存此次请求的秒数。在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据,非常有用,大幅优化请求次数
*/
/**
* 想要 发送cookie的话 那么就需要 Access-Control-Allow-Origin 设置 指定的域 request.getHeader("Origin") 这样应该可以
* 实现对单个域的信任是非常容易的事情。不过,如果需要信任多个域的话,那该怎么办呢?根据相关规范的建议,只需列出相关的域,并用空格加以分隔即可,例如:Access-Control-Allow-Origin:http://a.example.com http://example.com
* 但是,没有哪个浏览器真正支持这一特性。
*
* 于是,我们可以通过使用通配符来信任所有子域,具体方法是:
*
* Access-Control-Allow-Origin: *.example.com
* 可是有一些偷懒的程序员,将Access-Control-Allow-Origin设置为允许来自所有域*的跨域请求。
*
* Access-Control-Allow-Origin:*这样,所有的网站都可以对其进行跨域资源请求了,这是非常危险的。不过先别高兴的太早。其实这里在设计的时候有一个很好的限制。xmlhttprequest发送的请求需要使用 "withCredentials" 来带上Cookie,如果一个目标域设置成了允许任意域的跨域请求,这个请求又带着 Cookie 的话,这个请求是不合法的。(就是如果需要实现带 Cookie 的跨域请求,CORS服务端需要明确的配置允许来源的域,使用任意域的配置是不合法的)浏览器会屏蔽掉返回的结果。Javascript 就没法获取返回的数据了。这是CORS模型最后一道防线。假如没有这个限制的话,那么 Javascript 就可以获取返回数据中的 Cookie 和 CSRF Token,以及各种敏感数据。这个限制极大的降低了CORS的风险。
*
* 如下,这是不允许的:
*
* Access-Control-Allow-Origin: *
* Access-Control-Allow-Credentials: true
* 这样的话,就可以允许指定的源(http://example.com)来跨域请求服务器端的资源,并且服务器会响应。在默认情况下,发送跨域请求时不会携带cookie或其他凭据。因此,它不能用于窃取与用户相关的敏感信息(如CSRF令牌)。不过,网站服务器可以使用以下头部来启用凭据传输:
*/
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setStatus(200);
return true;
}
}