[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-strapi-article:zh:google-shopping-scraping-proxy-ip-region-results-access":3,"blog-article:\u002Fblog\u002Fgoogle-shopping-scraping-proxy-ip-region-results-access":632,"blog-related:\u002Fblog\u002Fgoogle-shopping-scraping-proxy-ip-region-results-access":633,"blog-translations:\u002Fblog\u002Fgoogle-shopping-scraping-proxy-ip-region-results-access":634},{"available":4,"article":5,"relatedArticles":130,"translations":553},true,{"source":6,"id":7,"documentId":8,"translationKey":8,"locale":9,"slug":10,"path":11,"_path":11,"title":12,"description":13,"excerpt":13,"image":14,"publishedAt":15,"updatedAt":16,"author":17,"tags":18,"featured":19,"sortOrder":20,"readingTime":21,"bodyType":22,"bodyBlocks":23,"bodyHtml":129},"strapi",3035,"b11ximfj5zgmye3d23zg05fr","zh","google-shopping-scraping-proxy-ip-region-results-access","\u002Fblog\u002Fgoogle-shopping-scraping-proxy-ip-region-results-access","Google Shopping 地区商品结果验证","Google Shopping 数据采集代理 IP 怎么配置？本文说明地区、币种、配送范围、库存和商户信息对商品结果的影响，并给出小样本验证与 403\u002F429 排查步骤。","https:\u002F\u002Fcms.quanqiudaili.com\u002Fuploads\u002Flarge_google_shopping_ip_cover_8a958ded51.webp","2026-10-01T14:15:33.536Z","2026-10-01T14:15:33.521Z","Global Proxies Team",[],false,0,2,"blocks",[24,30,34,39,43,48,52,56,60,64,68,72,77,81,85,89,93,97,101,105,109,113,117,121,125],{"type":25,"children":26},"paragraph",[27],{"text":28,"type":29},"Google Shopping 的商品、价格和商户结果不只取决于出口地区，还会受到币种、语言、配送地址、库存和采集时间影响。验证代理 IP 时应选择少量商品，固定除出口以外的全部条件，再比较价格、币种、商户与配送信息，避免把库存或实时价格变化误判成地区差异。","text",{"type":25,"children":31},[32],{"text":33,"type":29},"接入全球代理服务前先确认当前环境属于支持的海外网络环境；不在支持范围内时，应先确认服务适用条件。",{"type":35,"level":21,"children":36},"heading",[37],{"text":38,"type":29},"Google Shopping 的地区结果由哪些变量决定",{"type":25,"children":40},[41],{"text":42,"type":29},"记录国家或地区、语言、币种、配送地区、关键词、排序、分页和请求频率。第一次只选 3—5 个商品或关键词，确认出口地区后再对照商品字段；验证期间不要同时更换币种、配送地址和登录状态。",{"type":44,"children":45},"code",[46],{"text":47,"type":29},"| 任务 | 更合适的代理 IP | 重点记录 |\n| --- | --- | --- |\n| 多地区商品与价格观察 | 动态住宅代理 IP | 出口地区、币种、配送范围、采集时间 |\n| 带商户账号的连续检查 | 静态住宅代理 IP | 账号地区、Cookie、会话和出口一致性 |",{"type":35,"level":21,"children":49},[50],{"text":51,"type":29},"国家、币种、配送地与出口地区如何配合",{"type":25,"children":53},[54],{"text":55,"type":29},"按 HTTP、HTTPS 或 SOCKS5 配置主机、端口、账号和密码，可先参考 [代理 IP 参数与设置说明](https:\u002F\u002Fhelp.quanqiudaili.com\u002Fdocs\u002Fproxy-Settings)，再确认出口地区。建议只对公开网页做 3—5 个商品或关键词的小样本验证：固定国家\u002F地区、语言、币种、配送地区和分页，依次记录商品名称、价格、币种、商户、库存、配送范围、链接和采集时间。连续出现 403、429、验证码或结果异常时立即停止，不扩大样本。",{"type":35,"level":21,"children":57},[58],{"text":59,"type":29},"403、429 和商品结果异常怎么判断",{"type":25,"children":61},[62],{"text":63,"type":29},"403\u002F429 出现时停止扩大采集，先参考 [代理 IP 故障排查中心](https:\u002F\u002Fwww.quanqiudaili.com\u002Fblog\u002Fproxy-ip-troubleshooting-hub) 检查请求频率、分页、Cookie 和平台规则；价格或商户结果不一致时，先核对出口地区、语言、币种、配送地区、库存和采集时间。代理 IP 只能改变网络出口，不能保证库存、配送资格或实时价格一致。",{"type":25,"children":65},[66],{"text":67,"type":29},"涉及公开商品结果采样时，还应查看 [目标网站规则与合规采样](https:\u002F\u002Fwww.quanqiudaili.com\u002Fblog\u002Fproxy-ip-target-site-rules-compliant-sampling)。",{"type":35,"level":21,"children":69},[70],{"text":71,"type":29},"如何设计一组可复核的商品样本",{"type":35,"level":73,"children":74},3,[75],{"text":76,"type":29},"固定商品和地区条件",{"type":25,"children":78},[79],{"text":80,"type":29},"先固定国家\u002F地区、语言、币种、配送地区和分页，再用一个小样本核对商品名称、价格、商户和库存字段。若要进一步判断时间范围和归一化数据的影响，可对照 [Google Trends 代理 IP 配置指南](https:\u002F\u002Fwww.quanqiudaili.com\u002Fblog\u002Fgoogle-trends-proxy)。",{"type":35,"level":73,"children":82},[83],{"text":84,"type":29},"记录结果并设置停止条件",{"type":25,"children":86},[87],{"text":88,"type":29},"出口 IP 正确但价格或商户变化时，还要考虑库存、配送范围和实时数据变化。需要比较市场参数与搜索结果时，可继续查看 [Bing 搜索代理 IP 配置指南](https:\u002F\u002Fwww.quanqiudaili.com\u002Fblog\u002Fbing)。",{"type":44,"children":90},[91],{"text":92,"type":29},"| 检查项 | 需要记录的内容 |\n| --- | --- |\n| 地区条件 | 国家\u002F地区、语言、币种、配送地区 |\n| 请求条件 | 关键词、分页、排序、请求频率 |\n| 商品结果 | 商品名称、价格、币种、商户、库存、配送范围、链接、采集时间 |",{"type":25,"children":94},[95],{"text":96,"type":29},"Google 搜索结果会受到个性化和搜索位置影响，可查看 [Google 搜索个性化说明](https:\u002F\u002Fsupport.google.com\u002Fwebsearch\u002Fanswer\u002F12410098?hl=en) 与 [Google 搜索位置管理说明](https:\u002F\u002Fsupport.google.com\u002Fwebsearch\u002Fanswer\u002F179386?hl=en)。[Merchant Center 配送设置](https:\u002F\u002Fsupport.google.com\u002Fmerchants\u002Fanswer\u002F6324484?hl=en)只用于解释商家配送字段，不能单独证明消费者端 Shopping 结果。只有官方页面明确说明的设置才应作为确定配置项，无法确认的参数应标为待验证。",{"type":25,"children":98},[99],{"text":100,"type":29},"只有国家、币种、配送地、库存状态和采样时间都已记录，商品结果才适合扩大比较；价格或库存实时变化不能单独证明代理出口有问题。\n需要进行多地区、短会话的商品结果观察时，可进一步评估 [动态住宅代理 IP](https:\u002F\u002Fwww.quanqiudaili.com\u002Fproduct\u002Fdynamic-residential)。",{"type":35,"level":21,"children":102},[103],{"text":104,"type":29},"FAQ",{"type":35,"level":73,"children":106},[107],{"text":108,"type":29},"如何配置并确认 Google Shopping 采集请求已经走代理？",{"type":25,"children":110},[111],{"text":112,"type":29},"先填写主机、端口、账号和密码，再固定地区、语言、币种和分页，用一个最小请求核对出口 IP、商品价格和商户字段。",{"type":35,"level":73,"children":114},[115],{"text":116,"type":29},"商品价格或商户结果不一致时先检查什么？",{"type":25,"children":118},[119],{"text":120,"type":29},"先固定地区、币种、语言、分页和请求频率，再检查 IP 地区、商品库存与平台实时数据是否发生变化。",{"type":35,"level":73,"children":122},[123],{"text":124,"type":29},"什么时候应停止采集？",{"type":25,"children":126},[127],{"text":128,"type":29},"连续出现 403、429、验证码或结果明显异常时停止扩大规模，保留请求参数和错误记录并按平台规则处理。","",[131,254,417],{"source":6,"id":132,"documentId":133,"translationKey":133,"locale":9,"slug":134,"path":135,"_path":135,"title":136,"description":137,"excerpt":137,"image":138,"publishedAt":139,"updatedAt":140,"author":17,"tags":141,"featured":19,"sortOrder":20,"readingTime":21,"bodyType":22,"bodyBlocks":142,"bodyHtml":129},3037,"y6ot2xv3nw32h1po6tszsytm","poe-proxy-region-login-access-troubleshooting","\u002Fblog\u002Fpoe-proxy-region-login-access-troubleshooting","Poe 代理 IP 怎么配：地区限制、登录与访问失败排查","Poe 代理 IP 怎么配：地区限制、登录与访问失败排查，覆盖浏览器配置、Cookie 会话、地区验证和停止条件。","https:\u002F\u002Fcms.quanqiudaili.com\u002Fuploads\u002Flarge_poe_ip_cover_d741becdde.webp","2026-10-01T14:16:12.147Z","2026-10-01T14:16:12.134Z",[],[143,147,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,214,231,234,238,242,246,250],{"type":25,"children":144},[145],{"text":146,"type":29},"Poe 登录或访问异常时，先确认网页或客户端是否真的使用代理 IP，再区分出口 IP、Cookie 会话、账号状态和 Poe 服务规则。代理 IP 不能保证解除地区限制、通过审核或获得更高配额。",{"type":25,"children":148},[149],{"text":33,"type":29},{"type":35,"level":21,"children":151},[152],{"text":153,"type":29},"Poe 网页与客户端的代理接入差异",{"type":25,"children":155},[156],{"text":157,"type":29},"配置步骤应锁定一个已核验的浏览器与版本，写出系统代理或浏览器代理入口、四个字段位置、认证弹窗行为和启用后的出口验证；其他客户端只列为待验证，不把四字段清单当作完整入口。",{"type":25,"children":159},[160],{"text":161,"type":29},"本文主路径采用 Windows 11 系统代理：进入“设置 → 网络和 Internet → 代理 → 手动设置代理”，启用代理服务器后填写地址和端口；账号密码按系统认证提示输入。完成后在同一浏览器窗口先验证出口，再测试 Poe 登录，不能用其他浏览器标签的成功代替。",{"type":25,"children":163},[164],{"text":165,"type":29},"网页端是最容易复现的主路径：在实际打开 Poe 的浏览器中配置代理并检查出口 IP。桌面或移动客户端如果没有明确的独立代理入口，应通过系统代理或代理客户端接管；不要凭另一浏览器的检测结果判断 Poe 客户端已经生效。",{"type":25,"children":167},[168],{"text":169,"type":29},"按“代理协议 → 主机 → 端口 → 账号\u002F密码 → 启用代理 → IP 检测”的顺序操作。浏览器代理和系统代理的接管范围可能不同，必须在实际访问 Poe 的同一浏览器中验证出口 IP。",{"type":25,"children":171},[172],{"text":173,"type":29},"登录前记录出口 IP 所在地区、浏览器语言、时区和 Cookie 状态。需要长期保持同一地区时，静态住宅代理 IP 通常比频繁轮换的动态住宅代理 IP 更容易复测，但不能替代正常账号行为。",{"type":35,"level":21,"children":175},[176],{"text":177,"type":29},"如何验证出口 IP 所在地区和登录会话",{"type":25,"children":179},[180],{"text":181,"type":29},"先在实际访问 Poe 的入口中打开 IP 检测页，确认出口 IP 已变化；再打开 Poe，记录登录状态、页面语言、重定向和验证码提示。只改一个变量复测，才能判断差异来自代理 IP、Cookie 还是账号状态。",{"type":35,"level":21,"children":183},[184],{"text":185,"type":29},"Cookie、验证码和访问失败怎么排查",{"type":25,"children":187},[188],{"text":189,"type":29},"1. IP 未变化：检查浏览器是否绕过代理、系统代理是否冲突。\n2. 407：核对代理协议、主机、端口、账号和密码。\n3. 反复登录或验证码：停止重复尝试，检查 Cookie、设备环境、账号状态和请求频率。\n4. 只有 Poe 打不开：对比其他网站，判断是 Poe 地区策略、账号状态还是服务异常。\n5. 401\u002F403\u002F429：分别检查登录认证、权限\u002F地区规则和请求频率\u002F配额。",{"type":25,"children":191},[192],{"text":193,"type":29},"固定一个变量后再复测，例如只更换代理 IP，不要同时更换浏览器、Cookie 和账号。",{"type":44,"children":195},[196],{"text":197,"type":29},"| 表现 | 优先判断 |\n| --- | --- |\n| IP 未变化 | 当前入口没有读取代理配置 |\n| 返回 407 | 代理认证或端口错误 |\n| 反复出现验证码 | Cookie、设备环境、账号状态或操作频率 |\n| 其他网站正常但 Poe 失败 | Poe 服务规则、登录状态或账号层问题 |",{"type":25,"children":199},[200],{"text":201,"type":29},"连续登录只会增加变量。出现重复验证码或相同错误时，应停止尝试并保存出口 IP 所在地区、Cookie 状态、错误时间和页面提示。",{"type":25,"children":203},[204],{"text":205,"type":29},"**能力边界：** 代理 IP 可以改善出口 IP 所在地区和网络路径，但不能替代 Cookie、账号状态、Poe 服务规则或配额。",{"type":35,"level":21,"children":207},[208],{"text":209,"type":29},"官方文档",{"type":25,"children":211},[212],{"text":213,"type":29},"Poe 的网页入口、客户端功能和账号政策可能变化，可参考：",{"type":215,"format":216,"children":217},"list","unordered",[218,223,227],{"type":219,"children":220},"list-item",[221],{"text":222,"type":29},"[Poe 官方帮助中心](https:\u002F\u002Fhelp.poe.com\u002Fhc\u002Fen-us)：核对登录、账号和产品使用问题。",{"type":219,"children":224},[225],{"text":226,"type":29},"[Poe 服务入口](https:\u002F\u002Fpoe.com\u002F)：确认当前页面状态和官方提示。",{"type":219,"children":228},[229],{"text":230,"type":29},"[MDN Cookie 文档](https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FHTTP\u002FCookies)：了解 Cookie 与登录会话。",{"type":35,"level":21,"children":232},[233],{"text":104,"type":29},{"type":35,"level":73,"children":235},[236],{"text":237,"type":29},"其他网站正常但 Poe 打不开怎么办？",{"type":25,"children":239},[240],{"text":241,"type":29},"说明基础网络和代理 IP 可能已经生效，应继续检查 Cookie、登录状态、账号提示、地区规则和 Poe 服务状态。",{"type":35,"level":73,"children":243},[244],{"text":245,"type":29},"代理配置正确但仍然失败怎么办？",{"type":25,"children":247},[248],{"text":249,"type":29},"保持浏览器、Cookie 和账号不变，把网络层、认证层、账号状态和服务权限分开复测；出现重复验证码时停止继续登录。",{"type":25,"children":251},[252],{"text":253,"type":29},"每次只调整一个变量，并保存出口 IP 所在地区、错误时间和页面提示。浏览器或系统代理尚未配置时，可先查看[代理设置帮助](https:\u002F\u002Fhelp.quanqiudaili.com\u002Fdocs\u002Fproxy-Settings)。",{"source":6,"id":255,"documentId":256,"translationKey":256,"locale":9,"slug":257,"path":258,"_path":258,"title":259,"description":260,"excerpt":260,"image":261,"publishedAt":262,"updatedAt":263,"author":17,"tags":264,"featured":19,"sortOrder":20,"readingTime":73,"bodyType":22,"bodyBlocks":265,"bodyHtml":129},3036,"pv7w1ycsh8d3o5bpw06btrt7","mistral-ai-proxy-web-api-configuration","\u002Fblog\u002Fmistral-ai-proxy-web-api-configuration","Mistral API 代理 IP：curl 与 Python Requests 配置","Mistral AI 代理 IP 配置指南：网页、API 与 Proxy URL，包含 curl、Python 请求、环境变量和错误码排查。","https:\u002F\u002Fcms.quanqiudaili.com\u002Fuploads\u002Flarge_mistral_ai_ip_api_proxy_url_cover_6ef6165455.webp","2026-10-01T14:15:53.732Z","2026-10-01T14:15:53.707Z",[],[266,270,273,277,281,285,289,293,297,301,305,309,313,317,321,325,329,333,337,341,363,369,373,376,380,394,397,401,405,409,413],{"type":25,"children":267},[268],{"text":269,"type":29},"Mistral AI 接入时要分清三件事：代理 IP 提供出口 IP，API Base URL 是服务地址，API Key 是服务认证。先用最小请求验证出口 IP 和认证，再接入 SDK 或业务代码。",{"type":25,"children":271},[272],{"text":33,"type":29},{"type":35,"level":21,"children":274},[275],{"text":276,"type":29},"Mistral API 请求中代理 URL、Base URL 和 API Key 的区别",{"type":25,"children":278},[279],{"text":280,"type":29},"当前正文实际覆盖 curl 与 Python Requests；如果不补网页登录流程和已核验版本的 SDK 示例，标题应理解为 API 配置指南，而不是完整的“网页、API 与 Proxy URL”教程。",{"type":25,"children":282},[283],{"text":284,"type":29},"代理 URL 决定请求经过哪个出口 IP，API Base URL 决定请求发送到哪个服务地址，API Key 则用于验证账户权限。三者位置不同，任何一个填错都会产生不同的错误。",{"type":25,"children":286},[287],{"text":288,"type":29},"请求链路可以理解为：`应用代码 → 代理 URL → Mistral API Base URL → API Key 验证`。代理连接成功只说明网络层可用，仍需等待 API 完成账户认证和模型权限判断。",{"type":35,"level":21,"children":290},[291],{"text":292,"type":29},"curl、Python 与 SDK 配置示例",{"type":25,"children":294},[295],{"text":296,"type":29},"```bash\ncurl --proxy http:\u002F\u002FUSER:PASSWORD@HOST:PORT \\\n-H \"Authorization: Bearer $MISTRAL_API_KEY\" \\\n-H \"Content-Type: application\u002Fjson\" \\\nhttps:\u002F\u002Fapi.mistral.ai\u002Fv1\u002Fmodels\n```",{"type":25,"children":298},[299],{"text":300,"type":29},"如果请求返回 407，先修代理认证；如果返回 401，先修 API Key。不要把代理 URL 当成 Mistral API Base URL，也不要把真实密钥写进代码或 Notebook。",{"type":35,"level":73,"children":302},[303],{"text":304,"type":29},"Python 与 SDK 配置",{"type":25,"children":306},[307],{"text":308,"type":29},"```python\nimport os, requests",{"type":25,"children":310},[311],{"text":312,"type":29},"proxies = {\n'http': os.environ['HTTP_PROXY'],\n'https': os.environ['HTTPS_PROXY'],\n}\nr = requests.get(\n'https:\u002F\u002Fapi.mistral.ai\u002Fv1\u002Fmodels',\nheaders={'Authorization': f\"Bearer {os.environ['MISTRAL_API_KEY']}\"},\nproxies=proxies,\ntimeout=15,\n)\nprint(r.status_code, r.text[:200])\n```",{"type":25,"children":314},[315],{"text":316,"type":29},"模型列表可读不等于模型调用有权限。若要验证实际调用，使用当前账户有权限且成本可控的模型，并记录状态码、耗时和脱敏请求标识；不要把一次成功响应写成所有模型均可调用。",{"type":25,"children":318},[319],{"text":320,"type":29},"```python\npayload = {\n'model': os.environ['MISTRAL_MODEL'],\n'messages': [{'role': 'user', 'content': 'Reply with OK'}],\n'max_tokens': 8,\n}\nresponse = requests.post(\n'https:\u002F\u002Fapi.mistral.ai\u002Fv1\u002Fchat\u002Fcompletions',\nheaders={'Authorization': f\"Bearer {os.environ['MISTRAL_API_KEY']}\"},\njson=payload,\nproxies=proxies,\ntimeout=30,\n)\nprint(response.status_code, response.text[:500])\n```",{"type":35,"level":21,"children":322},[323],{"text":324,"type":29},"模型请求验证和错误码排查",{"type":25,"children":326},[327],{"text":328,"type":29},"先用模型列表或其他轻量请求验证网络和 API Key，再测试实际模型请求。",{"type":25,"children":330},[331],{"text":332,"type":29},"两步验证可以避免把模型名称、请求体或配额错误误判为代理失败。保存脱敏后的状态码、错误类型、响应耗时和请求 ID（如响应中提供），通常比只记录“调用失败”更有排查价值。",{"type":25,"children":334},[335],{"text":336,"type":29},"接入 SDK 时继续使用 SDK 要求的 Base URL 和 API Key；代理只放在 HTTP 客户端层。网页访问、API 请求和服务端转发要分别验证。",{"type":35,"level":73,"children":338},[339],{"text":340,"type":29},"401、403、407、429 和上游错误",{"type":215,"format":216,"children":342},[343,347,351,355,359],{"type":219,"children":344},[345],{"text":346,"type":29},"**401**：API Key 缺失、错误或已失效。",{"type":219,"children":348},[349],{"text":350,"type":29},"**403**：账号权限、地区策略或服务规则。",{"type":219,"children":352},[353],{"text":354,"type":29},"**407**：代理 IP 认证失败。",{"type":219,"children":356},[357],{"text":358,"type":29},"**429**：接口配额、请求频率或并发超过限制。",{"type":219,"children":360},[361],{"text":362,"type":29},"**TLS\u002F超时**：检查代理协议、DNS、地区路径和客户端超时。",{"type":215,"format":216,"children":364},[365],{"type":219,"children":366},[367],{"text":368,"type":29},"**5xx**：检查上游服务状态、中间链路和重试策略，不要无限重试。",{"type":25,"children":370},[371],{"text":372,"type":29},"**能力边界：** 即使代理请求成功，API Key、模型权限、账户配额和服务策略仍需单独满足。",{"type":35,"level":21,"children":374},[375],{"text":209,"type":29},{"type":25,"children":377},[378],{"text":379,"type":29},"Mistral API 路径、SDK 和模型列表可能更新，配置前可核对：",{"type":215,"format":216,"children":381},[382,386,390],{"type":219,"children":383},[384],{"text":385,"type":29},"[Mistral AI API 文档](https:\u002F\u002Fdocs.mistral.ai\u002Fapi\u002F)：确认端点、请求格式和错误响应。",{"type":219,"children":387},[388],{"text":389,"type":29},"[Mistral AI SDK 文档](https:\u002F\u002Fdocs.mistral.ai\u002Fgetting-started\u002Fclients\u002F)：确认当前 SDK 的客户端配置方式。",{"type":219,"children":391},[392],{"text":393,"type":29},"[MDN HTTP Authorization](https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FHTTP\u002FHeaders\u002FAuthorization)：了解 Authorization 请求头。",{"type":35,"level":21,"children":395},[396],{"text":104,"type":29},{"type":35,"level":73,"children":398},[399],{"text":400,"type":29},"Mistral AI Proxy URL 适合什么场景？",{"type":25,"children":402},[403],{"text":404,"type":29},"适合在服务端或开发环境中为 Mistral API 请求提供出口 IP。它不会替代 API Key、模型权限或接口配额。",{"type":35,"level":73,"children":406},[407],{"text":408,"type":29},"curl 成功但 SDK 请求失败怎么办？",{"type":25,"children":410},[411],{"text":412,"type":29},"说明代理和 API Key 基本可用，应继续检查 SDK 是否读取代理环境变量、Base URL、模型名称、请求体和超时配置。",{"type":25,"children":414},[415],{"text":416,"type":29},"先用 curl 验证代理认证和 API Key，再验证模型列表，最后运行真实模型请求。需要核对代理 IP 的协议、主机、端口和认证字段时，可参考[代理设置帮助](https:\u002F\u002Fhelp.quanqiudaili.com\u002Fdocs\u002Fproxy-Settings)。",{"source":6,"id":418,"documentId":419,"translationKey":419,"locale":9,"slug":420,"path":421,"_path":421,"title":422,"description":423,"excerpt":423,"image":424,"publishedAt":425,"updatedAt":426,"author":17,"tags":427,"featured":19,"sortOrder":20,"readingTime":73,"bodyType":22,"bodyBlocks":428,"bodyHtml":129},3034,"nmdqvydupk50smvasa92jwjs","http-proxy-middleware-websocket-troubleshooting","\u002Fblog\u002Fhttp-proxy-middleware-websocket-troubleshooting","http-proxy-middleware WebSocket 配置与升级失败排查","http-proxy-middleware WebSocket 配置与升级失败排查，提供 Node.js 示例、Upgrade 检查和 407\u002F502\u002F504 排障步骤。","https:\u002F\u002Fcms.quanqiudaili.com\u002Fuploads\u002Flarge_http_proxy_middleware_websocket_cover_311279d93f.webp","2026-10-01T14:15:13.043Z","2026-10-01T14:15:13.025Z",[],[429,433,437,441,445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,512,516,530,533,537,541,545,549],{"type":25,"children":430},[431],{"text":432,"type":29},"普通 HTTP 请求能成功，不代表 WebSocket 一定能升级。先让 Node.js 服务通过代理 IP 访问目标，再检查 `Upgrade`、超时、TLS 和服务端 `upgrade` 事件。",{"type":35,"level":21,"children":434},[435],{"text":436,"type":29},"http-proxy-middleware 的 HTTP 与 WebSocket 转发边界",{"type":25,"children":438},[439],{"text":440,"type":29},"普通请求完成一次响应即可结束；WebSocket 则需要客户端发起 Upgrade、中间件转发握手、目标服务返回 101，并持续保持双向连接。任何一层未处理 Upgrade，都可能出现“网页请求正常、WebSocket 失败”。",{"type":25,"children":442},[443],{"text":444,"type":29},"普通 HTTP 代理请求和 WebSocket Upgrade 是两条不同链路；`ws: true` 只表示中间件允许升级，不代表目标服务、代理 IP 和超时配置已经兼容。",{"type":35,"level":21,"children":446},[447],{"text":448,"type":29},"Node.js 中间件配置与 101 握手验证",{"type":25,"children":450},[451],{"text":452,"type":29},"`createProxyMiddleware` 的反向转发不等于额外出站代理。若目标链路还需要代理 IP，应从环境变量读取代理 URL，并传入与目标协议匹配的 Agent；否则本文只讨论反向转发，不应暗示已自动使用指定代理出口。",{"type":25,"children":454},[455],{"text":456,"type":29},"```js\nimport http from 'node:http';\nimport { createProxyMiddleware } from 'http-proxy-middleware';\nimport { HttpsProxyAgent } from 'https-proxy-agent';",{"type":25,"children":458},[459],{"text":460,"type":29},"const outboundAgent = new HttpsProxyAgent(process.env.PROXY_URL);",{"type":25,"children":462},[463],{"text":464,"type":29},"const app = createProxyMiddleware({\ntarget: 'https:\u002F\u002Ftarget.example.com',\nchangeOrigin: true,\nws: true,\nagent: outboundAgent,\nproxyTimeout: 15000,\non: {\nerror(err, req) {\nconsole.error('proxy error', req.url, err.message);\n},\n},\n});",{"type":25,"children":466},[467],{"text":468,"type":29},"const server = http.createServer((req, res) => app(req, res));\nserver.on('upgrade', (req, socket, head) => app.upgrade(req, socket, head));\nserver.listen(3000);\n```",{"type":25,"children":470},[471],{"text":472,"type":29},"这里的 `ws: true` 允许 WebSocket 转发，`proxyTimeout` 控制上游等待时间，`upgrade` 事件负责把升级请求交给中间件。成功测试不应只看 101，还要确认客户端可以收发消息，并记录连接关闭代码与原因。",{"type":25,"children":474},[475],{"text":476,"type":29},"示例按 `http-proxy-middleware` v3 的 `on.error` 事件结构编写；旧版本可能仍使用 `onError`，发布前应按项目锁定版本核对。",{"type":25,"children":478},[479],{"text":480,"type":29},"实际项目还要确认代理 IP 的协议、主机、端口和认证方式由客户端或上游连接层正确读取。不要把 WebSocket 的 Upgrade 头当作代理协议。",{"type":35,"level":73,"children":482},[483],{"text":484,"type":29},"如何验证 101 Switching Protocols",{"type":25,"children":486},[487],{"text":488,"type":29},"1. 先用同一代理参数请求普通 HTTP URL，确认出口 IP 和状态码。\n2. 再发起 WebSocket 握手，检查请求是否包含 `Connection: Upgrade` 和 `Upgrade: websocket`。\n3. **407** 查代理认证；**400\u002F401** 查目标握手和权限；**502\u002F504** 查 Node、中间代理和目标服务日志。\n4. 连接建立后立即断开，重点检查 `proxyTimeout`、目标服务关闭策略和反向代理缓冲。\n5. 固定 URL、代理 IP、客户端版本和超时参数，一次只改一个变量。",{"type":35,"level":21,"children":490},[491],{"text":492,"type":29},"407、400、502、504 和连接断开怎么排查",{"type":25,"children":494},[495],{"text":496,"type":29},"按客户端、中间件、代理 IP 和目标服务四层查看日志，一次只修改协议、认证、Upgrade、超时或目标路径中的一个变量。",{"type":44,"children":498},[499],{"text":500,"type":29},"| 表现 | 优先检查 |\n| --- | --- |\n| 407 | 代理主机、端口和认证 |\n| 400\u002F401 | Upgrade 参数、目标路径或目标权限 |\n| 502\u002F504 | 中间件、上游连接和超时 |\n| 建立后立即关闭 | 心跳、读取超时和目标服务关闭策略 |",{"type":35,"level":73,"children":502},[503],{"text":504,"type":29},"代理 IP 应配置在哪一层",{"type":25,"children":506},[507],{"text":508,"type":29},"代理 IP应由实际发起上游连接的客户端或连接 Agent 读取，不能只在浏览器端配置后假定 Node.js 服务也会继承。",{"type":35,"level":21,"children":510},[511],{"text":209,"type":29},{"type":25,"children":513},[514],{"text":515,"type":29},"`http-proxy-middleware` 的事件 API 可能随主版本变化，运行前应核对：",{"type":215,"format":216,"children":517},[518,522,526],{"type":219,"children":519},[520],{"text":521,"type":29},"[http-proxy-middleware 官方文档](https:\u002F\u002Fgithub.com\u002Fchimurai\u002Fhttp-proxy-middleware)：确认当前版本的配置和事件回调。",{"type":219,"children":523},[524],{"text":525,"type":29},"[Node.js HTTP Upgrade](https:\u002F\u002Fnodejs.org\u002Fapi\u002Fhttp.html#event-upgrade)：了解服务端 Upgrade 事件。",{"type":219,"children":527},[528],{"text":529,"type":29},"[WebSocket 协议 RFC 6455](https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc6455)：查看握手、控制帧和关闭机制。",{"type":35,"level":21,"children":531},[532],{"text":104,"type":29},{"type":35,"level":73,"children":534},[535],{"text":536,"type":29},"为什么普通请求成功，WebSocket 仍失败？",{"type":25,"children":538},[539],{"text":540,"type":29},"普通请求只证明网络连通，WebSocket 还需要完成 Upgrade 握手、双向消息收发和长连接保持。",{"type":35,"level":73,"children":542},[543],{"text":544,"type":29},"返回 101 后连接立即断开怎么办？",{"type":25,"children":546},[547],{"text":548,"type":29},"101 只证明握手完成。继续检查心跳、读取超时、目标服务关闭策略，以及客户端记录的关闭代码和原因。",{"type":25,"children":550},[551],{"text":552,"type":29},"验证顺序应是普通 HTTP → 101 握手 → 消息收发 → 长连接保持。代理认证或端口仍不确定时，可先使用[智能检测助手](https:\u002F\u002Fhelp.quanqiudaili.com\u002Fdocs\u002FSmart-check)。",[554],{"source":6,"id":7,"documentId":8,"translationKey":8,"locale":9,"slug":10,"path":11,"_path":11,"title":12,"description":13,"excerpt":13,"image":14,"publishedAt":15,"updatedAt":16,"author":17,"tags":555,"featured":19,"sortOrder":20,"readingTime":21,"bodyType":22,"bodyBlocks":556,"bodyHtml":129},[],[557,560,563,566,569,572,575,578,581,584,587,590,593,596,599,602,605,608,611,614,617,620,623,626,629],{"type":25,"children":558},[559],{"text":28,"type":29},{"type":25,"children":561},[562],{"text":33,"type":29},{"type":35,"level":21,"children":564},[565],{"text":38,"type":29},{"type":25,"children":567},[568],{"text":42,"type":29},{"type":44,"children":570},[571],{"text":47,"type":29},{"type":35,"level":21,"children":573},[574],{"text":51,"type":29},{"type":25,"children":576},[577],{"text":55,"type":29},{"type":35,"level":21,"children":579},[580],{"text":59,"type":29},{"type":25,"children":582},[583],{"text":63,"type":29},{"type":25,"children":585},[586],{"text":67,"type":29},{"type":35,"level":21,"children":588},[589],{"text":71,"type":29},{"type":35,"level":73,"children":591},[592],{"text":76,"type":29},{"type":25,"children":594},[595],{"text":80,"type":29},{"type":35,"level":73,"children":597},[598],{"text":84,"type":29},{"type":25,"children":600},[601],{"text":88,"type":29},{"type":44,"children":603},[604],{"text":92,"type":29},{"type":25,"children":606},[607],{"text":96,"type":29},{"type":25,"children":609},[610],{"text":100,"type":29},{"type":35,"level":21,"children":612},[613],{"text":104,"type":29},{"type":35,"level":73,"children":615},[616],{"text":108,"type":29},{"type":25,"children":618},[619],{"text":112,"type":29},{"type":35,"level":73,"children":621},[622],{"text":116,"type":29},{"type":25,"children":624},[625],{"text":120,"type":29},{"type":35,"level":73,"children":627},[628],{"text":124,"type":29},{"type":25,"children":630},[631],{"text":128,"type":29},null,[],[]]