前后端分离----跨域篇笔记
程序员文章站
2022-07-10 17:55:30
...
上篇文章书写了前后端分离,在此再叙述一下
前后端分离的划分时按照职责划分
前端:VIew(视图层) Controller(控制层)
后台:Model(数据操作) Service(业务逻辑)
不同之处:
部署的不同:
传统:后台代码和前端页面全部部署到一个tomcat中
分离:可以将静态资源(html,js,css,img...)部署到一个专门的静态资源服务器,例如nginx
代码的不同
传统:接口返回的通常是渲染后的html文档
分离:接口返回的通常都是json
分离后的优点
降低了耦合度,前后端之间可以尽可能少的涉及彼此的代码逻辑
分离了关注的,可以让后台更加专注的解决业务逻辑数据访问、系统构架
扩展性提高了,可以搭配不同平台的前端
前后端分离后会出现最常见的跨域问题
什么是跨域?
浏览器在解析js代码时,发现js代码请求了了一个不属于当前服务器的资源,这时就称为跨域访问
为什么会有这个问题出现?
由于浏览器遵循同源策略,导致了无法访问跨域资源。。。。
同源策略是?
同源策略是浏览器的核心安全机制,其不允许在页面中解析执行来自其他服务器数据
同源限制
不允许访问非同源网页的Cookie、LocalStorage 和 IndexedDB。
不允许向非同源地址发送ajax请求。
怎么判断是否同源?
协议,端口,IP
如果三者之一有一个不同,则跨域了
那么请问移动端存在跨域问题吗?
no!不存在,同源策略是浏览器的策略
跨域问题解决方案
既然禁止跨域问题是浏览器的行为,那么只需要设置浏览器允许解析跨域请求的数据即可,但是这个设置必须放在服务器端,由服务器端来判断对方是否可信任
在响应头中添加一个字段,告诉浏览器,某个服务器是可信的
即在header中添加允许访问的地址,在响应头中明确指出即可
*表示 允许所有来源的跨域访问 (测试时用,正式部署需要指定为静态资源服务器地址)
例如:
response.setHeader("Access-Control-Allow-Origin","*");
其值可以是某个或多个指定的域名,也可以是*表示信任所有地址
一个可以这样解决,两个三个呢?更多呢?此时可以使用过滤器,而且不用写死相应地址。即动态设置跨域
package com.cx.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
/**
*
*/
@WebFilter(urlPatterns = "/*")
public class CROSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//动态设置 通过代码获取origin 判断要不要允许跨域
//允许跨域的主机地址列表
ArrayList<String> hosts = new ArrayList<>();
hosts.add("http://127.0.0.1:8020");
hosts.add("http://localhost:8020");
HttpServletRequest request = (HttpServletRequest)servletRequest;
//判断对方是否在允许的范围
if (hosts.contains(request.getHeader("Origin"))){
//从请求中获取Origin的值
((HttpServletResponse)servletResponse).setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
其他相关设置
//指定允许其他域名访问
//指定允许其他域名访问
'Access-Control-Allow-Origin:http://XXX.XXX.XXX'//一般用法(*,指定域,动态设置),注意*不允许携带认证头和cookies
//预检查间隔时间
'Access-Control-Max-Age: 1800'
//允许的请求类型
'Access-Control-Allow-Methods:GET,POST,PUT,POST'
//列出必须携带的字段
'Access-Control-Allow-Headers:x-requested-with,content-type'
补充:cookie跨域
默认情况下cookie是不允许跨域传输的.可以通过以下方式来解决
第一步
浏览器端设置允许cookie跨域
第二步
服务器端在响应中添加字段,说明允许cookie跨域
该值只能是true,为false无效,默认为false
#'Access-Control-Allow-Credentials:true'
上一篇: 在用SSM做项目的时候遇到的一些小坑