欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前后端分离----跨域篇笔记

程序员文章站 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'
相关标签: 前后端分离