如何解决CORS跨域问题

文章介绍了前端跨域的概念及其由浏览器的同源策略导致的原因。接着详细讲解了CORS(跨域资源共享)机制,以及如何通过设置Access-Control-Allow-Origin响应头来解决跨域问题。提供了两种解决方案,包括简单的设置通配符和更安全的指定特定域名。最后,给出了一个Java实现的Filter示例,用于在服务器端控制允许跨域的源。
摘要由CSDN通过智能技术生成

如何解决前端跨域问题

一、什么是跨域,什么是跨域资源共享(CORS)

1.什么是跨域

跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制

同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;具体来讲,同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现;同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。—百度百科

2.什么是跨域资源共享(CORS)

引用百度百科的解释。CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

3.如何解决跨域问题

3-1.简单的解决方式

为了解决跨域问题,Access-Control-Allow-Origin 该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。在后端添加 Filter 过滤器,设置请求头即可,如下:response.setHeader(“Access-Control-Allow-Origin”, “*”);

3-2.较为完善的解决方式

为了防止骇客利用跨域漏洞进行攻击,一般不写通配符 *,一般写的是请求时Origin字段的值,例如通过 http://localhost:8081 的前端页面访问 http://localhost:8080 的接口,Header头设置如下: response.setHeader(“Access-Control-Allow-Origin”, “http://localhost:8081”);

二、代码实现

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;

/**
 *
 * @author c
 * @version $Revision: 1.4 $ 2023-3-29 下午4:01:27
 */
public class HeadFilter implements Filter {
	@Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void doFilter(ServletRequest request, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
		HttpServletResponse response = (HttpServletResponse) resp;
		HttpServletRequest req = (HttpServletRequest)request;
		// 获取请求的域(Origin)
		String origin = req.getHeader("Origin");
		// 如果是自己请求自己(使用测试工具调用接口或直接在浏览器中输入接口访问,非浏览器中的某个网页端中调用接口),则设置 origin 为 requestURL
		if (origin == null) {
			origin = req.getRequestURL().toString();
		}
		// 添加被信任url
		List<String> allowedOrigins = new ArrayList<>();
		// 接口地址
		allowedOrigins.add("http://localhost:8080");
		// 前端地址
		allowedOrigins.add("http://localhost:8081");
		// 如果请求的域在被信任的url中,则认可前端的访问;反之,则拒绝访问,跳转至 error.html 页面
		Boolean refererFlag = false;
		for (String allowedOrigin : allowedOrigins) {
			if (origin.startsWith(allowedOrigin)){
				refererFlag = true;
				break;
			}
		}
		if(refererFlag){
			// 解决跨域访问报错问题
			response.setHeader("Access-Control-Allow-Origin", origin);
			chain.doFilter(request, response);
		}else{
			response.setHeader("Referrer-Policy", "no-referrer");
			request.getRequestDispatcher("error.html").forward(request,response);
		}
	}
	/**
	 * @see Filter#init(FilterConfig)
	 */
	@Override
	public void init(FilterConfig filterConfig) {

	}
	@Override
	public void destroy() {

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值