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

Angular PWA集成share_target API失败,请求返回504错误求助

解决方案:Angular PWA对接WhatsApp语音分享504/405错误修复

问题定位

核心问题是share_target的POST请求在Service Worker中处理逻辑不当:

  • 导入ngsw-worker.js在底部时,自定义拦截逻辑未及时响应请求导致超时触发504
  • 导入在顶部时,Angular SW未拦截POST请求,直接透传到服务器触发nginx 405(服务器不允许POST方法)

分步修复方案

1. 编写自定义Service Worker拦截逻辑

创建src/custom-sw.js,先处理POST请求再导入Angular官方SW,确保请求不会透传也不会超时:

// 拦截share_target的POST请求
self.addEventListener('POST', (event) => {
  // 匹配manifest中配置的share_target action路径
  if (event.request.url.endsWith('/share-target')) {
    event.respondWith(
      (async () => {
        // 解析表单数据,提取WhatsApp分享的语音文件
        const formData = await event.request.formData();
        const audioFile = formData.get('file');
        
        // 将音频文件存入专用缓存,供应用后续读取
        const cache = await caches.open('shared-audio-cache');
        await cache.put('latest-voice', new Response(audioFile));
        
        // 返回成功响应,避免WhatsApp端超时判定
        return new Response(JSON.stringify({ status: 'success' }), {
          headers: { 'Content-Type': 'application/json' }
        });
      })()
    );
  }
});

// 导入Angular官方Service Worker,处理其余请求
importScripts('./ngsw-worker.js');

2. 修正Manifest的share_target配置

确保manifest.json中的参数与拦截逻辑匹配:

"share_target": {
  "action": "/share-target",
  "method": "POST",
  "enctype": "multipart/form-data",
  "params": {
    "files": [
      {
        "name": "file",
        "accept": ["audio/*"]
      }
    ]
  }
}

3. 调整Angular构建配置

在angular.json中指定自定义SW,并确保其被打包到产物中:

"projects": {
  "your-project-name": {
    "architect": {
      "build": {
        "options": {
          "serviceWorker": true,
          "ngswConfigPath": "src/ngsw-config.json",
          "assets": [
            "src/favicon.ico",
            "src/assets",
            "src/manifest.json",
            "src/custom-sw.js" // 添加自定义SW到资源列表
          ]
        }
      }
    }
  }
}

4. 配置Angular SW排除共享路径

在ngsw-config.json中,让官方SW不处理/share-target路径:

"navigationUrls": [
  "!/share-target", // 排除该路径
  "/**"
]

5. 应用端读取缓存的音频文件

在Angular组件中,读取缓存的语音文件并调用Whisper API:

async loadSharedAudio() {
  const cache = await caches.open('shared-audio-cache');
  const response = await cache.match('latest-voice');
  if (response) {
    const audioBlob = await response.blob();
    // 调用OpenAI Whisper API转写音频
    this.transcribeAudio(audioBlob);
  }
}

async transcribeAudio(blob: Blob) {
  const formData = new FormData();
  formData.append('file', blob, 'voice-message.mp3');
  formData.append('model', 'whisper-1');
  
  try {
    const response = await fetch('https://api.openai.com/v1/audio/transcriptions', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${yourOpenAIKey}`
      },
      body: formData
    });
    const result = await response.json();
    console.log('转写结果:', result.text);
  } catch (err) {
    console.error('转写失败:', err);
  }
}

关键说明

  • 先处理POST请求再导入官方SW,既避免请求透传触发405,又能及时返回响应防止504超时
  • 用缓存存储音频文件,确保应用启动后能获取到分享的内容
  • 无需在nginx配置中允许/share-target的POST方法,因为请求已被SW拦截处理

内容的提问来源于stack exchange,提问作者Paul R.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:56:23