React应用使用webdav库请求时出现CORS与预检401错误如何解决
问题根本原因
- 你误将CORS响应头作为请求头添加:
Access-Control-Allow-Origin等Access-Control-*开头的头是服务端返回给浏览器的响应头,前端请求携带此类头完全无效,还会额外增加预检请求的校验项。 - WebDAV服务对OPTIONS预检请求要求身份校验:浏览器CORS规范明确要求,预检OPTIONS请求不得携带Authorization等身份凭证头,你的服务端对所有请求(包括OPTIONS)都要求基础身份校验,所以预检直接返回401未授权,CORS校验失败,浏览器不会发送后续真实的PROPFIND请求。
解决方案
1. 修正前端代码
删除createClient配置中headers里的所有CORS相关响应头,修改后代码如下:
const getItems = async() => { const client = createClient( "https://mywebdavurl.com/", { authType: AuthType.Password, username: "user", password: "passwd" // 删掉所有Access-Control开头的请求头配置 } ); console.log(client) const directoryItems = await client.getDirectoryContents("/"); console.log(directoryItems); }
2. 配置WebDAV服务端(推荐方案)
你当前使用Nginx做WebDAV服务,在对应的Nginx配置块中添加OPTIONS请求特殊处理,跳过鉴权并返回正确CORS头:
location / { # 你原有的WebDAV配置保留 dav_methods PUT DELETE MKCOL COPY MOVE; dav_ext_methods PROPFIND OPTIONS; # ...其他原有配置 # 新增CORS和OPTIONS请求处理 set $cors ''; if ($http_origin ~* ^http://localhost:3001$) { # 生产环境替换为你的正式前端域名 set $cors '1'; } if ($request_method = OPTIONS) { set $cors "${cors}options"; } if ($cors = '1options') { add_header Access-Control-Allow-Origin "$http_origin"; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS, PROPFIND, COPY, MOVE, MKCOL"; add_header Access-Control-Allow-Headers "Authorization, Depth, Content-Type"; add_header Access-Control-Allow-Credentials "true"; add_header Content-Length 0; add_header Content-Type text/plain; return 204; } if ($cors = '1') { add_header Access-Control-Allow-Origin "$http_origin"; add_header Access-Control-Allow-Credentials "true"; add_header Access-Control-Expose-Headers "Content-Length, Content-Type"; } # 原有auth_basic配置保留即可,OPTIONS请求已经提前返回204不会走到鉴权逻辑 auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; }
配置完成后重启Nginx即可生效。
3. 开发环境临时替代方案(无需改服务端)
如果暂时无法修改服务端配置,开发阶段可以使用React自带的代理功能规避CORS问题:
- 在React项目的
package.json中添加配置项:"proxy": "https://mywebdavurl.com/" - 修改createClient的实例化地址为本地开发地址:
const client = createClient( "/", // 改为相对路径,请求会自动转发到proxy配置的WebDAV地址 { authType: AuthType.Password, username: "user", password: "passwd" } );
- 重启React开发服务,此时所有请求为同源请求,不会触发CORS校验。
生产环境可通过Nginx反向代理将前端资源和WebDAV接口统一到同一个域名下,从根源上避免CORS问题。
内容的提问来源于stack exchange,提问作者Rensykes
相关产品推荐
相关产品推荐

