Java中如何有效解决跨域资源共享问题?

2026-04-30 06:172阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1114个文字,预计阅读时间需要5分钟。

Java中如何有效解决跨域资源共享问题?

问题:在页面上要使用Ajax请求去获取另一个服务的的数据,由于浏览器的同源策略,直接请求会得到一个Error。错误信息:Failed to load https://www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource.

问题

在页面上要使用 Ajax 请求去获取另外一个服务的数据,由于浏览器的 同源策略,所以直接请求会得到一个 Error。

Failed to load www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

大概就是这样的一个错误,关键词是 Access-Control-Allow-Origin,一般出现这个都是跨域问题。

解决方案

解决跨域问题的方式有很多,但这里之说 Cors 的方案。

在后台添加一个 Filter 过滤器

/** * 使用自定义的 Filter 拦截器实现跨域请求、 * 适用于所有的 Java Web 项目并且不局限于某个框架 * 注:此处的 @Component 仅为让 Spring 知道这个 Bean, 不然拦截器不会加载 * * @author rxliuli */ public class CustomCorsFilterConfig implements Filter { @Override public void init(FilterConfig filterConfig) { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //允许所有来源 String allowOrigin = "*"; //允许以下请求方法 String allowMethods = "GET,POST,PUT,DELETE,OPTIONS"; //允许以下请求头 String allowHeaders = "Content-Type,X-Token,Authorization"; //允许有认证信息(cookie) String allowCredentials = "true"; String origin = request.getHeader("Origin"); //此处是为了兼容需要认证信息(cookie)的时候不能设置为 * 的问题 response.setHeader("Access-Control-Allow-Origin", origin == null ? allowOrigin : origin); response.setHeader("Access-Control-Allow-Methods", allowMethods); response.setHeader("Access-Control-Allow-Credentials", allowCredentials); response.setHeader("Access-Control-Allow-Headers", allowHeaders); //处理 OPTIONS 的请求 if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } filterChain.doFilter(request, response); } @Override public void destroy() { } }

在 web.xml 文件中添加拦截器配置(注:如果可能就配置成第一个 Filter)

<!--cors 跨域访问--> <filter> <filter-name>customCorsFilterConfig</filter-name> <filter-class>CustomCorsFilterConfig</filter-class> </filter> <filter-mapping> <filter-name>customCorsFilterConfig</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Spring Web 的解决方案

配置一个每次请求都过滤一次的 Filter 就好了

@Configuration public class CorsConfig { @Bean public OncePerRequestFilter corsFilter() { return new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //允许所有来源 String allowOrigin = "*"; //允许以下请求方法 String allowMethods = "GET,POST,PUT,DELETE,OPTIONS"; //允许以下请求头 String allowHeaders = "Content-Type,X-Token,Authorization"; //允许有认证信息(cookie) String allowCredentials = "true"; String origin = request.getHeader("Origin"); //此处是为了兼容需要认证信息(cookie)的时候不能设置为 * 的问题 response.setHeader("Access-Control-Allow-Origin", origin == null ? allowOrigin : origin); response.setHeader("Access-Control-Allow-Methods", allowMethods); response.setHeader("Access-Control-Allow-Credentials", allowCredentials); response.setHeader("Access-Control-Allow-Headers", allowHeaders); //处理 OPTIONS 的请求 if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } filterChain.doFilter(request, response); } }; } }

使用示例

下面是一些简单的使用 fetch 进行跨域请求的示例:

  • 简单 fetch 请求,和正常使用 fetch 并无区别

fetch(url) .then(res => res.json()) .then(json => console.log(json))

  • 表单请求

var fd = new FormData() fd.append('username', 'rx') fd.append('password', 'rx') fetch(url, { method: 'POST', body: fd, }) .then(res => res.json()) .then(json => console.log(json))

  • 需要认证的请求

fetch(url, { /** * 关键就在这里,代表用户是否应该在跨域的情况下发送 cookies 和 HTTP Basic authentication 等验信息以及服务端能否返回 Set-Cookie(服务端 Session 需要使用这个向 cookie 中设置 sessionId)。 * 包含三个可选值:omit(从不发送), same-origin(同源才发送), include(总会发送) * 参考链接:<developer.mozilla.org/zh-CN/docs/Web/API/Request/credentials> */ credentials: 'include', }) .then(res => res.json()) .then(json => console.log(json))

注:如果想要服务端返回 Set-Cookie(SessionId 也需要通过这个响应属性去设置) 就必须设置这个请求参数!

Java中如何有效解决跨域资源共享问题?

那么,之后在前端跨域请求的时候就可以愉快地玩耍啦(v^_^)v

以上就是Java 跨域问题的处理方式的详细内容,更多关于Java 跨域的资料请关注易盾网络其它相关文章!

本文共计1114个文字,预计阅读时间需要5分钟。

Java中如何有效解决跨域资源共享问题?

问题:在页面上要使用Ajax请求去获取另一个服务的的数据,由于浏览器的同源策略,直接请求会得到一个Error。错误信息:Failed to load https://www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource.

问题

在页面上要使用 Ajax 请求去获取另外一个服务的数据,由于浏览器的 同源策略,所以直接请求会得到一个 Error。

Failed to load www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

大概就是这样的一个错误,关键词是 Access-Control-Allow-Origin,一般出现这个都是跨域问题。

解决方案

解决跨域问题的方式有很多,但这里之说 Cors 的方案。

在后台添加一个 Filter 过滤器

/** * 使用自定义的 Filter 拦截器实现跨域请求、 * 适用于所有的 Java Web 项目并且不局限于某个框架 * 注:此处的 @Component 仅为让 Spring 知道这个 Bean, 不然拦截器不会加载 * * @author rxliuli */ public class CustomCorsFilterConfig implements Filter { @Override public void init(FilterConfig filterConfig) { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //允许所有来源 String allowOrigin = "*"; //允许以下请求方法 String allowMethods = "GET,POST,PUT,DELETE,OPTIONS"; //允许以下请求头 String allowHeaders = "Content-Type,X-Token,Authorization"; //允许有认证信息(cookie) String allowCredentials = "true"; String origin = request.getHeader("Origin"); //此处是为了兼容需要认证信息(cookie)的时候不能设置为 * 的问题 response.setHeader("Access-Control-Allow-Origin", origin == null ? allowOrigin : origin); response.setHeader("Access-Control-Allow-Methods", allowMethods); response.setHeader("Access-Control-Allow-Credentials", allowCredentials); response.setHeader("Access-Control-Allow-Headers", allowHeaders); //处理 OPTIONS 的请求 if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } filterChain.doFilter(request, response); } @Override public void destroy() { } }

在 web.xml 文件中添加拦截器配置(注:如果可能就配置成第一个 Filter)

<!--cors 跨域访问--> <filter> <filter-name>customCorsFilterConfig</filter-name> <filter-class>CustomCorsFilterConfig</filter-class> </filter> <filter-mapping> <filter-name>customCorsFilterConfig</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Spring Web 的解决方案

配置一个每次请求都过滤一次的 Filter 就好了

@Configuration public class CorsConfig { @Bean public OncePerRequestFilter corsFilter() { return new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //允许所有来源 String allowOrigin = "*"; //允许以下请求方法 String allowMethods = "GET,POST,PUT,DELETE,OPTIONS"; //允许以下请求头 String allowHeaders = "Content-Type,X-Token,Authorization"; //允许有认证信息(cookie) String allowCredentials = "true"; String origin = request.getHeader("Origin"); //此处是为了兼容需要认证信息(cookie)的时候不能设置为 * 的问题 response.setHeader("Access-Control-Allow-Origin", origin == null ? allowOrigin : origin); response.setHeader("Access-Control-Allow-Methods", allowMethods); response.setHeader("Access-Control-Allow-Credentials", allowCredentials); response.setHeader("Access-Control-Allow-Headers", allowHeaders); //处理 OPTIONS 的请求 if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } filterChain.doFilter(request, response); } }; } }

使用示例

下面是一些简单的使用 fetch 进行跨域请求的示例:

  • 简单 fetch 请求,和正常使用 fetch 并无区别

fetch(url) .then(res => res.json()) .then(json => console.log(json))

  • 表单请求

var fd = new FormData() fd.append('username', 'rx') fd.append('password', 'rx') fetch(url, { method: 'POST', body: fd, }) .then(res => res.json()) .then(json => console.log(json))

  • 需要认证的请求

fetch(url, { /** * 关键就在这里,代表用户是否应该在跨域的情况下发送 cookies 和 HTTP Basic authentication 等验信息以及服务端能否返回 Set-Cookie(服务端 Session 需要使用这个向 cookie 中设置 sessionId)。 * 包含三个可选值:omit(从不发送), same-origin(同源才发送), include(总会发送) * 参考链接:<developer.mozilla.org/zh-CN/docs/Web/API/Request/credentials> */ credentials: 'include', }) .then(res => res.json()) .then(json => console.log(json))

注:如果想要服务端返回 Set-Cookie(SessionId 也需要通过这个响应属性去设置) 就必须设置这个请求参数!

Java中如何有效解决跨域资源共享问题?

那么,之后在前端跨域请求的时候就可以愉快地玩耍啦(v^_^)v

以上就是Java 跨域问题的处理方式的详细内容,更多关于Java 跨域的资料请关注易盾网络其它相关文章!