fish2018/pansou · error
入口脚本未找到搜索路由
Error message
入口脚本未找到搜索路由
What it means
Once the entry JS bundle is downloaded, the plugin locates the literal client-side search route "/s/$query" with strings.Index. If the route string is absent, it cannot derive where the search API identifier is defined and returns this error. The site's JavaScript no longer contains that route literal.
Solutions
- Download the asset and grep for the current search route; update the "/s/$query" literal in the plugin to the new route string.
- If the route moved to another chunk, adjust assetPath extraction (indexAssetPattern) or scan all script chunks until the route is found.
- Check whether the string is now escaped in the bundle (e.g. "\/s\/$query") and normalize assetBody before searching.
- Upgrade the plugin to a release matching the current site.
Example fix
// before routeIndex := strings.Index(string(assetBody), "/s/$query") // after normalized := strings.ReplaceAll(string(assetBody), "\\/", "/") routeIndex := strings.Index(normalized, "/s/$query")
Defensive patterns
Strategy: fallback
Validate before calling
assetBody, err := fetchAsset()
if err == nil && !strings.Contains(string(assetBody), "/s/$query") {
log.Printf("route literal missing from bundle; site likely updated")
} Type guard
func hasSearchRoute(body []byte) bool { return strings.Index(string(body), "/s/$query") >= 0 } Try / catch
funcID, err := discoverServerFunctionID(ctx, req)
if err != nil && strings.Contains(err.Error(), "入口脚本未找到搜索路由") {
log.Printf("xiaokupan route changed: %v", err)
return nil, errSkipPlugin
} Prevention
- Monitor for this error as a signal that the upstream site changed its routing.
- Search bundles with normalized strings (unescaped slashes) before giving up.
- Fall back to scanning all script chunks, not just the first entry asset.
When it happens
Trigger: strings.Index(string(assetBody), "/s/$query") returns -1: the entry bundle was fetched successfully but does not contain the search route literal — the site changed routing, the wrong script was fetched, or the response is minified/encoded differently.
Common situations: Upstream framework upgrade renamed routes (e.g. "/search?q="); the fetched asset is a loader chunk rather than the route-defining chunk; a build changed string encoding (template literals, escaped slashes).
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/bc3b0c831c81cd68.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/xiaokupan/xiaokupan.go:253
assetPath := string(indexAssetPattern.Find(homeBody))
if assetPath == "" {
return "", fmt.Errorf("首页未找到入口脚本")
}
assetReq, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(p.baseURL, "/")+assetPath, nil)
if err != nil {
return "", err
}
assetReq.Header.Set("User-Agent", req.Header.Get("User-Agent"))
assetReq.Header.Set("Referer", homeURL)
assetBody, err := doLimitedRequest(client, assetReq, maxDiscoveryBodySize)
if err != nil {
return "", fmt.Errorf("读取入口脚本失败: %w", err)
}
routeIndex := strings.Index(string(assetBody), "/s/$query")
if routeIndex < 0 {
return "", fmt.Errorf("入口脚本未找到搜索路由")
}
windowStart := max(0, routeIndex-2048)
hashes := hashPattern.FindAll(assetBody[windowStart:routeIndex], -1)
if len(hashes) == 0 {
return "", fmt.Errorf("入口脚本未找到搜索接口标识")
}
return string(hashes[len(hashes)-1]), nil
}
func parseSearchResponse(body []byte) ([]model.SearchResult, error) {
var root serovalNode
if err := stdjson.Unmarshal(body, &root); err != nil {
return nil, fmt.Errorf("解析 Seroval 响应失败: %w", err)
}
decoder := newSerovalDecoder(&root)
resultNode := decoder.objectValue(&root, "result")
searchResultsNode := decoder.objectValue(resultNode, "searchResults")
mergedNode := decoder.objectValue(searchResultsNode, "merged_by_type")View on GitHub (pinned to beaa561337)