跨域相关
同源策略
同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到 XSS、CSFR 等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源。
同源策略限制内容有:
-
Cookie、LocalStorage、IndexedDB 等存储性内容
-
DOM 节点
-
AJAX 请求发送后,结果被浏览器拦截
但在html 中是有标签允许跨域
<img src=XXX>
<link href=XXX>
<script src=XXX>
而在实际应用开发中 第三种情况是我们最常见,即阻止一个域的javascript脚本和另外一个域的内容进行交互。
跨域:
客户端请求服务端,当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。
常见跨域场景
跨域解决方案
1.JSONP
原理: 利用 script 标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP 请求一定需要对方的服务器做支持才可以。
优缺点: JSONP 优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持 get 方法具有局限性,不安全可能会遭受 XSS 攻击。
JSONP 的实现流程:
-
声明一个回调函数,其函数名(如 show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的 data)。
-
创建一个script标签,把那个跨域的 API 数据接口地址,赋值给 script 的 src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)。
-
服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是 show,它准备好的数据是show(‘我不爱你’)。
-
最后服务器把准备的数据通过 HTTP 协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作。
前端代码
<script> //原理 // function test() { // var url = "http://localhost:8081/test?callback=handleCallback"; // var script = document.createElement('script'); // script.setAttribute("type","text/javascript"); // script.src = url; // document.body.appendChild(script); // } //ajax + jquery function test() { $.ajax({ type: "get", url: "http://localhost:8081/test", data: {}, jsonp: "callback",//->把传递函数名的那个形参callback,可省略 dataType: "jsonp", //指定服务器返回的数据类型 jsonpCallback: "handleCallback", //指定回调函数名称 如果不指定 jquery+ajax 会自动生成一个 success: function (data) { alert(JSON.stringify(data)) } }); } function handleCallback(data) { console.log(JSON.stringify(data)) alert(JSON.stringify(data)) } </script>
@GetMapping("/test") public void ttt(@RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "nums", defaultValue = "10") Integer nums, HttpServletRequest request, HttpServletResponse response) throws IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); List<Article> articles = articleService.selectList(new EntityWrapper<Article>().orderBy("article_publish_time")); String jsonArray = JSONObject.toJSONString(articles); String callback = request.getParameter("callback2"); System.out.println(callback); String rs = callback + "(" + jsonArray + ")"; response.getWriter().write(rs); }
2.CORS
1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin
2、带cookie跨域请求:前后端都需要进行设置
第一种:
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedHeaders("*") .allowedMethods("*") .maxAge(3600) .allowCredentials(true);//允许携带cookie }
第二种还需要前端也进行配置,如下:
$.ajax({ url: 'http://localhost:8080/test', type: 'get', data: {}, xhrFields: { withCredentials: true // 前端设置是否带cookie }, crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie });
3.nginx
windows上安装配置启动~~ netstat -an|findstr 80
前端去请求nginx服务http://localhost/ nginx转发到http://localhost:8081/
function test() { $.ajax({ type: "get", url: "http://localhost:80/test", data: {}, success: function (data) { alert(JSON.stringify(data)) } }); }
nginx配置
参考:https://cloud.tencent.com/developer/article/1477798
参考:https://cloud.tencent.com/developer/article/1595018
跨域解决方案还有其他
Cookie session
参考文章:https://blog.csdn.net/qq_28296925/article/details/80921585
默认情况下 ajax 请求 cookie 是不允许跨域的
可以通过在ajax 中设置以及后端项目设置
前端
// 4.cors_ajax
function testCookie1() {
$.ajax({
type: "get",
url: "http://localhost:8081/generate",
dataType: "", //指定服务器返回的数据类型
data: {},
crossDomain:true,
xhrFields: { withCredentials: true },
success: function (data) {
console.log("请求成功")
}
});
}
function testCookie2() {
$.ajax({
type: "get",
url: "http://localhost:8081/getCookie",
dataType: "", //指定服务器返回的数据类型
data: {},
crossDomain:true,
xhrFields: { withCredentials: true },
success: function (data) {
console.log("请求成功")
}
});
}
后端
@Configuration
@Slf4j
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*")
.maxAge(3600)
.allowCredentials(true);//设置允许携带cookie
}
}
html5中的Web Storage
参考文档 https://cloud.tencent.com/developer/article/1549171
参考文档 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/sessionStorage