fetch配合java web配置CORS跨域

本文介绍了CORS跨域的基本概念,包括简单请求和非简单请求的区别。重点讲解了Java Web如何配置允许CORS请求,包括在响应头中设置Access-Control-Allow-Origin等字段。同时,提到了预检请求(OPTIONS)的机制以及在fetch请求中启用withCredentials发送cookie的注意事项。最后,展示了使用过滤器在Java Web中实现CORS配置的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

跨域:不符合浏览器同源策略的请求不能执行,同源即域名、协议、端口都相同。这里主介绍CORS。

CORS两种请求:

  • 简单请求 simple request
    • 请求方法为HEAD、GET、POST之中任意一个
    • 请求头只有以下字段
      • Accept
      • Accept-Language
      • Content-Language
      • Last-Event-ID
      • Content-type (只限于用application/x-www-form-urlencoded、multipart/form-data、text/plain)
  • 非简单请求 not-so-simple request
    • 不满足简单请求条件都属于非简单请求

简单请求

  • 简单请求

    浏览器发出CORS请求,就是在头信息中增加一个Origin字段,用来说明此次请求是由那个源(协议、域名、端口)供服务器参考选择是否同意请求。如果服务器允许,会在响应头中添加如下字段:

    • Access-Control-Allow-Origin:

      如果服务器允许某个源进行访问则该字段为必要字段,他的值一般与请求头中的Origin字段相同,设置成*代表允许所有请求,但存在安全问题,并且在要发送cookie的情况中不适用。

    • Access-Control-Allow-Credentials:

      可选字段布尔类型,表示是否允许发送cookie。

    • Access-Control-Expose-Headers

      可选字段,CORS请求中,XMLHTTPRequest对象getResponseHeader()方法只能拿到6个基本字段,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。若需要其他,则需要在这里指定。

    • 客户端cookie问题:

      CORS请求默认不发送cookie和http认证信息,如果要发送cookie,除了服务端认证之外:

      Access-Control-Allow-Credentials: true
      

      还需要请求打开withCredentials属性,js中:

      var xhr = new XMLHttpRequest();
      xht.withCredentials = true;
      

      fetch中:

      options.headers = {
          credentials: 'include',
      }
      fetch(url,options)
      

非简单请求

非简单CORS请求会在正式通信前先发送一个OPTIONS类型的预检(preflight)请求。服务器在响应头中添加一些字段通知浏览器是否可以请求,否则报错。

  • 预检请求一般为OPTIONS请求,请求头中包含以下信息:

    • Origin 请求源
    • Access-Control-Request-Method
      请求会使用哪些方法
    • Access-Control-Request-Headers
      该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段
  • 预检请求回应

        Access-Control-Allow-Credentials:true
        Access-Control-Allow-Headers:Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token
        Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE
        Access-Control-Allow-Origin:http://demo.com.cn
        Access-Control-Max-Age:0
        Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
        Content-Length:0
        Content-Type:text/html;charset=UTF-8
        Date:Wed, 27 Dec 2017 00:18:29 GMT
        Server:Apache-Coyote/1.1
        XDomainRequestAllowed:1
    

    其中,关键字段为Access-Control-Allow-Origin:...
    表示同意了跨域请求。如果服务器拒绝了预检请求,则会没有该字段和相关字段。

java web配置允许CORS请求

java编写的服务端应用程序配置CORS方法很多,原理差不多,介绍一种简单实现:手动编写过滤器:

    public class CorsFilter implements Filter{
    public void init(FilterConfig filterConfig) throws ServletException {  
    // TODO Auto-generated method stub  

    }  

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,  
    ServletException {  
    // TODO Auto-generated method stub  
    HttpServletResponse res = (HttpServletResponse) response;  
    HttpServletRequest req = (HttpServletRequest)request;
    String origin = req.getHeader("Origin");
    res.setContentType("text/html;charset=UTF-8");  
       res.setHeader("Access-Control-Allow-Origin", origin);  
       res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
       res.setHeader("Access-Control-Max-Age", "0");  
       res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");  
       res.setHeader("Access-Control-Allow-Credentials", "true");  
       res.setHeader("XDomainRequestAllowed","1");  
       chain.doFilter(request, response);  
    }  

    public void destroy() {  
    // TODO Auto-generated method stub  

    }  
}

在web.xml中注册过滤器:

    <filter>  
     <filter-name>cors</filter-name>  
     <filter-class>com.mysoft.filter.CorsFilter</filter-class>  
    </filter>  
    <filter-mapping>  
     <filter-name>cors</filter-name>  
     <url-pattern>/*</url-pattern>  
    </filter-mapping> 

fetch请求也要有一定修改:

    fetch('http://172.0.0.1:8000/api/getAllUser', {
        method: 'POST',
        body: params,
        mode:'cors',
        headers: {
            'Content-Type': 'application/json',
             credentials: 'include',
             Accept: 'application/json',
        }
      });

主要是添加mode:'cors'

### 解决 fetch 请求中 Base64 转换导致的 CORS 问题 当使用 `fetch` 发送带有 Base64 编码的数据时,可能会遇到资源共享 (CORS) 的问题。这是因为服务器未正确配置以处理来自不同源的请求[^1]。 #### 配置服务器端支持 CORS 为了使服务器能够接受并响应请求,需确保其设置了合适的 CORS 头部信息。例如,在 Node.js 中可以借助 `cors` 包来实现这一功能: ```javascript const express = require('express'); const cors = require('cors'); // 引入 cors 包 const app = express(); app.use(cors()); // 允许来自任何源的请求 ``` 上述代码片段展示了如何通过中间件启用全局 CORS 支持[^2]。如果需要更精细地控制允许的名或其他参数,则可以通过传递选项给 `cors()` 方法完成自定义设置。 #### 修改 Fetch 请求头部 客户端发起 `fetch` 请求前应加入必要的预检请求头 (`Access-Control-Request-Method`) 和实际请求中的特定方法声明(如 PUT)。这有助于告知目标资源预期的操作方式以及所需权限级别: ```javascript fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Access-Control-Request-Method': 'PUT' // 明确指定 HTTP 动词 }, body: JSON.stringify({ data: base64Data }) }) .then(response => response.blob()) // 将 responseType 设置为 blob 来接收二进制数据流 .catch(error => console.error('Error:', error)); ``` 这里还调整了 `responseType` 属性至 `'blob'` 类型以便更好地兼容图片或者其他多媒体文件形式的内容传输需求[^3]。 #### 总结 综合以上措施——即合理配置服务端 CORS 策略与优化前端 fetch API 使用习惯两方面入手,可有效规避由 Base64 数据交换引发的相关异常状况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值