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

如何阻止HttpClient调用预签名URL时添加网关服务器域名

Fix Angular HttpClient Appending Gateway Domain to AWS S3 Presigned URLs

This is a super common headache when working with Angular + AWS S3 presigned URLs, and it almost always boils down to global HTTP interceptors or base URL configs overriding absolute URLs. Let’s walk through how to fix this properly:

1. Pinpoint the Root Cause

Angular’s HttpClient only appends a base URL to relative paths (like /api/upload). If your full S3 presigned URL (which should look like https://your-bucket.s3.amazonaws.com/your-file?X-Amz-Signature=...) is getting prefixed with your gateway domain, 99% of the time it’s because you have an HTTP interceptor that adds your API base URL to every request without checking if the URL is already absolute.

2. Fix the HTTP Interceptor

If you’re using an interceptor to inject your API base URL, modify it to skip absolute URLs. Here’s how to adjust it:

Before (Broken)

@Injectable()
export class BaseUrlInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // This appends the base URL to EVERY request, including S3's absolute URLs
    const modifiedRequest = request.clone({
      url: environment.apiBaseUrl + request.url
    });
    return next.handle(modifiedRequest);
  }
}

After (Fixed)

@Injectable()
export class BaseUrlInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Check if the URL is already absolute (starts with http/https)
    const isAbsoluteUrl = /^https?:\/\//i.test(request.url);
    
    if (!isAbsoluteUrl) {
      // Only append base URL to relative paths
      const modifiedRequest = request.clone({
        url: environment.apiBaseUrl + request.url
      });
      return next.handle(modifiedRequest);
    }
    
    // Let absolute S3 URLs pass through unchanged
    return next.handle(request);
  }
}

3. Clean Up Your Upload Code

Your current code has a subtle issue with the Content-Type header that could cause S3 signature validation failures. FormData automatically sets the correct multipart/form-data header, so manually overriding it can break the presigned URL’s signature. Here’s the improved version:

private save(presignedUri: string, file: File): Observable<HttpEvent<any>> {
  const formData: FormData = new FormData();
  formData.append('file', file);

  const req = new HttpRequest('POST', presignedUri, formData, {
    reportProgress: true,
    responseType: 'text',
    // Optional: Disable credentials since S3 doesn't need your app's cookies
    withCredentials: false
  });

  return this.http.request(req);
}

4. Double-Check the Presigned URL

Make sure your backend is returning a full absolute URL (not a relative path) for the presigned URI. If it’s sending something like /s3/upload?signature=... instead of https://your-bucket.s3.us-east-1.amazonaws.com/..., HttpClient will automatically append your gateway domain.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:22:49