作为全栈开发工程师相信大家肯定都遇到过前后端联调跨域问题吧!那么我们今天就来掰开了,揉碎了 ,来带着大家一起了解跨域。
1.什么是跨域
跨域是指浏览器不能执行其他网站的脚本语言。它是同源策略造成的,是浏览器对Js的一种安全限制,也可以说是浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议三者之间任意一个不同就会产生跨域。
例如,从 http://www.domain1.com/index.html 中使用ajax请求 http://www.domain2.com/servelet/ser1 ,就算这是通过JavaScript发起的请求,但其实质是浏览器发起的HTTP请求,因此遵循同源策略的限制,脚本只能访问和所属文档在同一个域名下的窗口和文档,因此这种跨域访问是被禁止的。
解决跨域有多种方式,例如JSONP、CORS等。其中CORS是目前使用最广泛的一种解决跨域问题的方式,它通过在HTTP响应头中添加相关参数,实现了浏览器与服务器之间的跨域数据传输12。
2.什么是同源策略
同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
好 现在就知道了什么是跨域 ,以及跨域产生的原因(不满足同源策略)了,那咱现在就唠唠该如何解决跨域问题呢。
3.跨域问题的解决办法
前端(jsonp)
什么是jsonp
首先JSONP是JSON with Padding的略称,JSONP为民间提出的一种跨域解决方案,通过客户端的script标签发出的请求方式原理就是通过添加一个
不过这种办法也有些不太美的地方比如:
只支持GET请求且不安全,可能遇到XSS攻击,不过它的好处是可以向老浏览器或不支持CORS的网站请求数据
前端代码 (jsonp)
好! 那就多了不说少了不唠 直接双手奉上一段jsonp代码以便与各位大佬使用
// 原生的实现方式
let script = document.createElement('script');
script.src = 'http://www.wxyweb.com';
document.body.a(script)
function callback(res) {
console.log(res)
}
// jquery实现
$.ajax({
url:'http://www.nealyang.cn/login',
type:'GET',
dataType:'jsonp', // 请求方式为jsonp(jsonp 非官方的数据交互协议)
jsonpCallback:'callback',
data:{
"username":"Nealyang"
}
})
好 那咱前端的jsonp解决跨域问题就算完成了 , 因为我以前也是做前端的,深知前端解决跨域问题的繁琐性,所以重点来了哦,老弟自学java,所谓打不过就加入的原则,深入java了解其解决跨域的问题,自从学习的java 妈妈再也不用担心我的跨域问题了 ,简直易如反掌啊。
回想第一次写项目时,后端让我一个前端独自解决跨域时的无助,我学习后只能说:“**************************”
后端spring注解(@CrossOrigin)
在controller方法上添加注解
@CrossOrigin(origins = {“http://127.0.0.1:8082”})
后端跨域配置文件(常见)
package com.xinzhi.demo.config;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class HttpFilter implements Filter {
/**
*
CROS跨域常用header
Access-Control-Allow-Origin: 允许哪些ip或域名可以跨域访问
Access-Control-Max-Age: 表示在多少秒之内不需要重复校验该请求的跨域访问权限
Access-Control-Allow-Methods: 表示允许跨域请求的HTTP方法,如:GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: 表示访问请求中允许携带哪些Header信息,如:Accept、Accept-Language、Content-Language、Content-Type
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//*号表示对所有请求都允许跨域访问
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Credentials", "true");
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT,OPTIONS");
res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
response.getWriter().println("Success");
return;
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
就是这么简单,现在想想还是有点生气 。 哈哈哈哈哈
nginx跨域
```java
# 在server下添加配置文件
#允许跨域请求的域,* 代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4e085b02b6d54685894897c907d09753.png#pic_center)如你所见这就是鄙人,5年开发史上学习到关于跨域的解决办法了 ,希望能给你带来一些帮助。