• Java基础之《网站跨域问题》


    一、什么是前后端分离架构

    1、传统web系统开发网站架构

    分成三层架构:
    com.xxx.dao:数据库访问层
    com.xxx.service:业务逻辑层
    com.xxx.controller:控制层(需要控制页面跳转)

    2、微服务架构

    前后端分离,专业的人做专业的事情。
    前端:前端工程师 vue ajax
    后端:后端工程师 go java php

    前端工程师承接了controller层页面的部分。

    二、什么是网站跨域问题

    1、网站访问

    2、跨域问题,发生在浏览器中安全策略

    跨域问题是浏览器的一种安全策略,访问需要遵循同源策略。

    发生了跨域的问题:
    可以请求到后端,但是无法获取到响应结果。
    前端vue地址为:vue.xxx.com
    后端接口地址为:api.xxx.com
    前端访问后端就不同源了。发送ajax请求的域名,和浏览器的域名不一样,浏览器会有一个保护机制。浏览器发送请求给后端,后端响应结果,浏览器会拦截。

    3、同源策略

    (1)浏览器访问的地址【协议://ip:端口】
    (2)在该页面中访问ajax请求【协议://ip:端口】必须要与我们浏览器所访问的【协议://ip:端口】一致。
    (3)如果不一致的话,则会发生跨域问题,浏览器触发保护机制,获取不到该请求的响应结果。

    三、什么情况下不会发生跨域问题

    1、nginx转发

    nginx发现html开头,转发到前端服务器。
    nginx发现api开头,转发到后端服务器。

    四、跨域有哪些解决方案

    解决跨域的问题:
    1、使用解决跨域的注解@CrossOrigin,底层就是在响应头中设置允许跨域的参数
    2、过滤拦截器aop,nginx、网关在响应头中设置允许跨域的参数
    3、使用nginx保证html与ajax接口,同协议、同ip(域名)、同端口
    4、Jsonp解决跨域的问题,不能使用post请求,只支持get请求,很少使用

    五、@CrossOrigin解决跨域的原理

    1、@CrossOrigin底层在响应头中,加上了一个参数
    Access-Control-Allow-Origin: *

    2、解决跨域问题原理

    就是在接口响应头,允许前端跨域访问该接口。

    1. HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
    2. response.setHeader("Access-Control-Allow-Origin", "*");

    六、自己封装一个@MyCrossOrigin注解

    1、注解底层原理实现
    aop+反射机制

    2、pom文件添加依赖

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-aopartifactId>
    4. dependency>

    3、添加注解类MyCrossOrigin.java

    1. package com.example.annotation;
    2. import java.lang.annotation.Documented;
    3. import java.lang.annotation.ElementType;
    4. import java.lang.annotation.Retention;
    5. import java.lang.annotation.RetentionPolicy;
    6. import java.lang.annotation.Target;
    7. @Target({ElementType.TYPE, ElementType.METHOD})
    8. @Retention(RetentionPolicy.RUNTIME)
    9. @Documented
    10. public @interface MyCrossOrigin {
    11. }

    4、添加注解处理类MyCrossOriginAop.java

    1. package com.example.annotation;
    2. import javax.servlet.http.HttpServletResponse;
    3. import org.aspectj.lang.annotation.Aspect;
    4. import org.aspectj.lang.annotation.Before;
    5. import org.springframework.stereotype.Component;
    6. import org.springframework.web.context.request.RequestContextHolder;
    7. import org.springframework.web.context.request.ServletRequestAttributes;
    8. @Aspect
    9. @Component
    10. public class MyCrossOriginAop {
    11. @Before(value = "@annotation(com.example.annotation.MyCrossOrigin)")
    12. public void before() {
    13. //如果接口上有加上该注解MyCrossOrigin,自动走前置通知的代码
    14. System.out.println("----------前置通知----------");
    15. HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
    16. response.setHeader("Access-Control-Allow-Origin", "*");
    17. }
    18. }

    5、在方法上使用@MyCrossOrigin注解

    1. package com.example.web;
    2. import java.util.HashMap;
    3. import javax.servlet.http.HttpServletResponse;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import org.springframework.web.bind.annotation.RestController;
    6. import org.springframework.web.context.request.RequestContextHolder;
    7. import org.springframework.web.context.request.ServletRequestAttributes;
    8. import com.example.annotation.MyCrossOrigin;
    9. @RestController
    10. public class CORSController {
    11. @RequestMapping("/hello2")
    12. @MyCrossOrigin
    13. public HashMap hello2() {
    14. HashMap result = new HashMap<>();
    15. result.put("code", "200");
    16. result.put("msg", "ok");
    17. // HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
    18. // response.setHeader("Access-Control-Allow-Origin", "*");
    19. return result;
    20. }
    21. }

    七、项目比较小的前后端分离方案

    1、注解@CrossOrigin

    2、过滤器—自己拦截每个请求

    3、在每个接口中加上Access-Control-Allow-Origin
    代码冗余,不推荐

    八、项目比较大的前后端分离方案

    1、基于nginx

    2、基于网关

    3、nginx反向代理

  • 相关阅读:
    Spring IoC源码:createBean(下)
    unity的debug.log无法显示console控制台
    C++ Reference: Standard C++ Library reference: Containers: deque: deque: swap
    PRBP20P-10/250C-EB、PRDP6G-10/30-CB电液比例直动式先导减压阀放大板
    【从零开始学习 SystemVerilog】7.11、SystemVerilog 类—— Shallow/Deep Copy(浅拷贝、深拷贝)
    光环:研发云搭建及人才梯队建设——姚冬
    Golang中读写CSV文件的全面指南
    npm常用命令与操作篇
    java中spark数据集字段下划线改成驼峰
    【股票价格走势预测】数据挖掘实验一
  • 原文地址:https://blog.csdn.net/csj50/article/details/127685729