主要出现在前后端分离项目
浏览器的同源策略,由于跨域不符合浏览器的同源策略,被浏览器拦截了
js
(脚本)中请求非同源(协议,ip
地址,端口号任何一个不相同认为不同源)的资源。http://localhost:8080/XXXX
, 在js(javascript脚本
)中是不允许请求http://localhost:9000
的因为不同源,只能请求8080
端口。js
中使用ajax
请求非同源服务器的数据,往往会引发跨域问题。跨域问题出现是因为再js
中请求了不同源(协议,ip
,端口不同)的服务器,只需要请求相同的源的服务器就可以解决这个问题,这就用到了代理,所有请求都请求相同的Node.js
或nginx
,对于部分请求(主要是获取静态资源的,不涉及跨域问题)直接返回对应资源,对于涉及跨域的请求,让node.js
或nginx
请求到对应资源再返回给浏览器,毕竟只有浏览器才有同源策略,服务器是没有的。
既然跨域浏览器不允许,那就直接告诉浏览器允许跨域----后端接口允许跨域,也可以解决跨域问题
如果不明白什么是代理,请阅读知识小贴士
没有代理,浏览器通过http://localhost:8080/home.htm
l获取html
网页数据,在html
页面向http://localhost:9000/xx
获取html
页面具体数据,由于浏览器同源策略请求是不允许的
通过nginx
或Node.js
代理后,获取url
为http//localhost:9000/xxx.html
的html
页面
获取url
为http://localhost:9000/api/xxx
页面内的数据 ,相同的http://localhost:9000
并不会引发跨域问题,只不过带api
前缀的被Node.js
或ngiinx
代理了,向http://localhost:8080/xxx
获取对应资源后再返回给客户端
实际解决问题(在前端添加代理配置)
在vue.config.js
中添加如下配置,只要是带api
前缀的都会被代理到http://localhost:9000
,请求路径
http://localhost:8080/api/xxx
被代理到http://localhost:9000/api/xxxx
这样解决了跨域问题问题
module.exports = {devServer:{proxy:{'/api':{//匹配所有以'/api'开头的请求路径target:'http://localhost:9000',//代理目标的基础路径changeOrigin:true, //可要可不要看具体需求pathRewrite:{'^/api':''} 可要可不要看具体需求} }}
}
CORS
(后端)cors概念
cors是w3c标准全称是跨域资源共享。
使用cors解决跨域问题
主要实现方式是在服务器端添加响应头Access-Control-Allow-Origin(允许请求的域) 和Access-Control-Allow-Methods(允许请求的方法)
@Configuration
public class CorsConfig implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) res;HttpServletRequest request = (HttpServletRequest) req;String origin = request.getHeader("Origin");if(origin!=null) {response.setHeader("Access-Control-Allow-Origin", origin);}String headers = request.getHeader("Access-Control-Request-Headers");if(headers!=null) {response.setHeader("Access-Control-Allow-Headers", headers);response.setHeader("Access-Control-Expose-Headers", headers);}response.setHeader("Access-Control-Allow-Methods", "*");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Credentials", "true");chain.doFilter(request, response);}@Overridepublic void init(FilterConfig filterConfig) {}@Overridepublic void destroy() {}
}
什么是代理?
是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,客户端向代理服务器发送一个请求并指定目标,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。
下一篇:Git命令使用笔记