You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Java REST API处理HTTP 302响应时无法下载Zip文件

问题:302重定向后curl无法下载Server B的文件

场景:访问Server A的Java REST API下载文件,当文件不存在时,Server A返回302重定向到同负载均衡下的Server B API,但执行curl命令后仅生成空的test.zip文件,verbose输出显示已收到302响应,但未发起对Server B的请求。

Server A的重定向代码:

String destinationUri = "https://serverB_IP/68629e2f-5157-4c0c-8ba8";
Response.ok().header("AuthToken", authToken).header("Access-Control-Allow-Origin", "https://"+serverA_IP).header("Access-Control-Allow-Method", HttpMethod.GET).header("Access-Control-Allow-Headers",ContentType.APPLICATION_OCTET_STREAM).status(302).location(destinationUri).build();

curl命令及响应:

curl -v -s -k -o test.zip -H "AuthToken: testToken" "https://serverA_IP/68629e2f-5157-4c0c-8ba8"
*   Trying 1xx.xx.xx.xxx:443...
* Connected to 1xx.xx.xx.xxx port 443
* schannel: disabled automatic use of client certificate
* schannel: using IP address, SNI is not supported by OS.
* ALPN: curl offers http/1.1
* ALPN: server did not agree on a protocol. Uses default.
* using HTTP/1.x
> GET /serverA_IP/68629e2f-5157-4c0c-8ba8 HTTP/1.1
> Host: 1xx.xx.xx.xxx
> User-Agent: curl/8.4.0
> Accept: */*
> AuthToken: testToken
>
< HTTP/1.1 302
< Date: Tue, 05 Mar 2024 16:18:27 GMT
< Server: Acme
< X-Content-Type-Options: nosniff
< Cache-Control: no-cache, no-store, must-revalidate
< Pragma: no-cache
< Expires: 0
< Strict-Transport-Security: max-age=631138519; includeSubDomains
< AuthToken: testToken
< Access-Control-Allow-Origin: https://serverA_IP
< Access-Control-Allow-Method: GET
< Access-Control-Allow-Headers: application/octet-stream
< Location: https://serverB_IP/68629e2f-5157-4c0c-8ba8
< Content-Type: application/octet-stream
< Content-Length: 0
< X-Frame-Options: DENY
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: default-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests; block-all-mixed-content;
<
* Connection #0 to host 1xx.xx.xx.xxx left intact

核心原因

curl默认不会自动跟随HTTP 3xx重定向,因此只会接收Server A返回的302响应(内容长度为0),不会主动请求Location头指向的Server B地址,最终生成空文件。

解决方案

1. 强制curl跟随重定向

添加-L(或--location)参数,让curl自动处理3xx重定向:

curl -v -s -k -L -o test.zip -H "AuthToken: testToken" "https://serverA_IP/68629e2f-5157-4c0c-8ba8"

2. 确保AuthToken传递到Server B

如果Server B的API同样需要AuthToken验证,curl默认不会将自定义头传递到重定向后的请求,需添加--location-trusted参数,允许将自定义头发送到重定向目标地址:

curl -v -s -k -L --location-trusted -o test.zip -H "AuthToken: testToken" "https://serverA_IP/68629e2f-5157-4c0c-8ba8"

代码优化建议(非当前问题直接原因)

Server A的重定向代码中,Response.ok().status(302)存在逻辑矛盾:ok()默认对应200状态码,后续手动设置302会覆盖,但规范写法应直接使用Response.status(302):

String destinationUri = "https://serverB_IP/68629e2f-5157-4c0c-8ba8";
Response.status(302)
        .header("AuthToken", authToken)
        .header("Access-Control-Allow-Origin", "https://"+serverA_IP)
        .header("Access-Control-Allow-Method", HttpMethod.GET)
        .header("Access-Control-Allow-Headers", ContentType.APPLICATION_OCTET_STREAM)
        .location(destinationUri)
        .build();

内容的提问来源于stack exchange,提问作者Code Trickle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 18:17:03