前后端分离跨域问题

浏览器跨域问题

浏览器是从两个方面去做这个同源策略的,一是针对接口的请求,二是针对Dom的查询。下面分别列举没有同源策略所会产生的问题。

1. CSRF

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

  1. 登录受信任网站A,并在本地生成Cookie(A)。
  2. 在cookie(A)未失效的情况下,登陆危险网站B
  3. 网站B去请求A

由于浏览器会自动带上网站A的用户cookie,所以网站A无法知道是用户的访问还是网站B进行的访问,这样B就相当于此用户进行了操作。这种要是发生在网上支付等会造成用户的损失。

2. Dom查询

我们可能会了解到一些短信诈骗情况,点击链接登录银行账户进行转账。比如中国银行的域名是www.zgyh.com,但是短信链接是www.zgyhh.com。这个页面内嵌了中国银行的登录页面,你可能就会进行登录。具体操作如下:

// HTML
<iframe name="zgyh" src="www.zgyh.com"></iframe>
// JS
// 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom
const iframe = window.frames['zgyh']
const username = iframe.document.getElementById('username')
const password = iframe.document.getElementById('password')
console.log("用户名:" + username +  ",密码:"+ password)

这样等于你在内嵌页面输入的信息我都能进行获取了。

怎样算跨域

所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子:

http://www.123.com 与 http://www.123.com(非跨域)

http://www.123.com 与 http://www.456.com (主域名不同:123/456,跨域)

http://abc.123.com 与 http://def.123.com (子域名不同:abc/def,跨域)

http://www.123.com:8080 与 http://www.123.com:8081 (端口不同:8080/8081,跨域)

http://www.123.com 与 https://www.123.com (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

Java后端的cors过滤器

一.自定义cors的filter
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CORSFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(CORSFilter.class);

    private List<String> corsOriginList;

    @Override
    public void destroy() {
          
    }  
  
    @Override  
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String curOrigin = request.getHeader("Origin");
        LOGGER.info("当前访问来源是:{}", curOrigin);
        // 从列表中获取,可以将数据放入缓存
        if (corsOriginList.contains(curOrigin)) {
            response.setHeader("Access-Control-Allow-Origin", curOrigin);
        } else {
            return ;
        }

        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(req, res);
    }
  
    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {
        corsOriginList = new ArrayList<String>();
        // 初始化可访问的域名列表
        corsOriginList.add("http://127.0.0.1:8888");
        corsOriginList.add("http://localhost:8888");
    }
  
}
二.配置filter
	<filter>
		<filter-name>cors</filter-name>
		<filter-class>com.limbo.survival.common.web.CORSFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>cors</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

基于nginx反向代理

一.nginx和反向代理

可以通过nginx的反向代理,将前后端应用放置到同一域。

所谓反向代理,就是在自己的域名下架设一个Web服务器,这个服务器会把请求转发给第三方服务器,然后把结果返回给客户端。这时候,在客户端看来,自己就是在和这台反向代理服务器打交道,而不知道第三方服务器的存在。

所以,如果有一个Web服务程序,它同时提供了反向代理功能和静态文件服务功能,静态文件服务负责渲染前端页面,反向代理则提供对第三方服务器的透明访问。那么前端和后端就变成了同源的,不再受同源策略的约束。

二.nginx配置
http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  www.web.com;
	
	# 对静态文件的匹配
	location ~* ^.+\.(xls|woff2|log|jpg|jpeg|gif|png|svg|ico|html|cfm|cfc|afp|asp|lasso|pl|py|txt|fla|swf|zip|wav|json|js|css|less)$ {
            # 前端跳转
            proxy_pass http://localhost:8888;
        }

	location /web/ {
			# 后端跳转
            proxy_pass http://localhost:8080;
	}

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        
    }
}
三.指定配置文件启动nginx
nginx -c /usr/local/etc/nginx/nginx.conf.my
四.前端访问路径

前端的访问路径都指向www.web.com

参考

### 若依框架前后端分离问题解决方案 #### CORS简介 资源共享(CORS,Cross-Origin Resource Sharing)是一种机制,它允许浏览器向不同源的服务器发出 XMLHttpRequest 请求。同源策略限制了从同一个源加载的文档或脚本如何与另一个源的资源进行交互[^1]。 #### 若依框架中的解决方式 在若依框架中,可以通过多种方式进行配置: 1. **使用 `@CrossOrigin` 注解** 在 Controller 层的方法或类上添加 `@CrossOrigin` 注解可以实现单个接口或整个控制器的支持。例如: ```java @RestController @RequestMapping("/example") @CrossOrigin(origins = "http://localhost:8080", maxAge = 3600) public class ExampleController { @GetMapping("/test") public String test() { return "Test Success"; } } ``` 上述代码表示 `/example/test` 接口允许来自 `http://localhost:8080` 的请求,并设置缓存时间为 3600 秒[^4]。 2. **全局配置 CORS 过滤器** 可以通过创建一个自定义的 Web 配置类来实现全局范围内的支持。以下是具体实现方法: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 对所有的路径生效 .allowedOrigins("*") // 允许所有名访问 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 支持的 HTTP 方法 .maxAge(3600L); // 缓存时间 (单位秒) } @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("http://localhost:8080"); } }; } } ``` 此种方式适用于需要统一管理规则的情况[^3]。 3. **Nginx反向代理** 如果不想修改后端代码,也可以通过 Nginx 来解决问题。配置如下: ```nginx server { listen 80; server_name your-domain.com; location /api/ { proxy_pass http://backend-server/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; } } ``` 使用此方法可以让前端和后端看起来像是同一源,从而规避问题[^2]。 #### 注意事项 - 当前主流推荐的方式是采用 CORS 技术,因为它更加灵活且易于维护。 - 如果涉及敏感数据传输,则需谨慎设置 `allowedOrigins` 参数,避免因开放过多权限而引发安全风险。 ```python print("以上为针对若依框架前后端分离时的问题解决方案") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值