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、解决跨域问题原理

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

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

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

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

2、pom文件添加依赖

<!--AOP支持-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

3、添加注解类MyCrossOrigin.java

package com.example.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyCrossOrigin {
	
}

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

package com.example.annotation;

import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class MyCrossOriginAop {

	@Before(value = "@annotation(com.example.annotation.MyCrossOrigin)")
	public void before() {
		//如果接口上有加上该注解MyCrossOrigin,自动走前置通知的代码
		System.out.println("----------前置通知----------");
		HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
		response.setHeader("Access-Control-Allow-Origin", "*");
	}
}

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

package com.example.web;

import java.util.HashMap;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.example.annotation.MyCrossOrigin;

@RestController
public class CORSController {

	@RequestMapping("/hello2")
	@MyCrossOrigin
	public HashMap<String, String> hello2() {
		HashMap<String, String> result = new HashMap<>();
		result.put("code", "200");
		result.put("msg", "ok");
		
//		HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
//		response.setHeader("Access-Control-Allow-Origin", "*");
		
		return result;
	}
}

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

1、注解@CrossOrigin

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

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

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

1、基于nginx

2、基于网关

3、nginx反向代理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值