{"record":{"id":"1bd76a7ae0a83393","repo":"fish2018/pansou","slug":"location","errorCode":null,"errorMessage":"重定向响应中没有Location头部","messagePattern":"重定向响应中没有Location头部","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/clxiong/clxiong.go","lineNumber":163,"sourceCode":"\t\tif i < MaxRetries-1 {\n\t\t\ttime.Sleep(RetryDelay)\n\t\t}\n\t}\n\n\tif lastErr != nil {\n\t\treturn \"\", lastErr\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查重定向响应\n\tif resp.StatusCode != 302 && resp.StatusCode != 301 {\n\t\treturn \"\", fmt.Errorf(\"期望302重定向，但得到状态码: %d\", resp.StatusCode)\n\t}\n\n\t// 从Location头部提取searchid\n\tlocation := resp.Header.Get(\"Location\")\n\tif location == \"\" {\n\t\treturn \"\", fmt.Errorf(\"重定向响应中没有Location头部\")\n\t}\n\n\t// 解析searchid\n\tsearchID := p.extractSearchIDFromLocation(location)\n\tif searchID == \"\" {\n\t\treturn \"\", fmt.Errorf(\"无法从Location中提取searchid: %s\", location)\n\t}\n\n\tif p.debugMode {\n\t\tlog.Printf(\"[CLXIONG] 获取到searchid: %s\", searchID)\n\t}\n\n\treturn searchID, nil\n}\n\n// extractSearchIDFromLocation 从Location头部提取searchid\nfunc (p *ClxiongPlugin) extractSearchIDFromLocation(location string) string {\n\t// location格式: \"result/?searchid=7549\"","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/clxiong/clxiong.go#L145-L181","documentation":"In getSearchID, the plugin expects the search endpoint to respond with a 302 redirect whose Location header carries the searchid. When the status code is 302 but the Location header is empty or missing, this error is thrown. It means the upstream server redirected without telling the client where to go, so the searchid cannot be obtained.","triggerScenarios":"Calling SearchWithResult when the upstream server returns HTTP 302 but omits the Location header — e.g. a broken redirect, an anti-bot interstitial responding 302 without a target, or a proxy stripping the Location header.","commonSituations":"Upstream site changed its redirect behavior or now serves an anti-bot/challenge page; a corporate or transparent proxy strips hop-by-hop headers; CDN misconfiguration returns 302 with no Location.","solutions":["Verify the upstream endpoint still returns a proper 302 with a Location header (curl -i on the search URL).","Check whether an anti-bot mechanism is intercepting the request; set realistic request headers (User-Agent, Referer, cookies) in the plugin's HTTP client.","Bypass or reconfigure any proxy between the client and the upstream that may strip the Location header.","If the site changed APIs, update the getSearchID flow to the new redirect/response scheme."],"exampleFix":"// before\nlocation := resp.Header.Get(\"Location\")\nif location == \"\" {\n    return \"\", fmt.Errorf(\"重定向响应中没有Location头部\")\n}\n// after (log status and headers for diagnosis)\nlocation := resp.Header.Get(\"Location\")\nif location == \"\" {\n    return \"\", fmt.Errorf(\"重定向响应中没有Location头部 (status=%d, ct=%s)\", resp.StatusCode, resp.Header.Get(\"Content-Type\"))\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"id, err := client.SearchWithResult(ctx, keyword)\nif err != nil {\n    if strings.Contains(err.Error(), \"没有Location头部\") {\n        // upstream redirect malformed: back off and retry later, or fall back to another plugin\n    } else {\n        return err\n    }\n}","preventionTips":["Send realistic browser headers so the upstream returns genuine redirects, not challenge pages","Test the search endpoint with curl -i whenever the plugin is deployed to a new network/proxy environment","Prefer plugins that fail gracefully; wrap calls so one broken upstream doesn't kill the whole search"],"tags":["http","redirect","missing-header","go"],"backgroundTag":"unexpected-response-shape","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}