{"record":{"id":"ed01908dc02daa9c","repo":"docmirror/dev-sidecar","slug":"cache-intercept-if-modified-since","errorCode":null,"errorMessage":"cache intercept: 解析 if-modified-since 失败: ","messagePattern":"cache intercept: 解析 if-modified-since 失败: ","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/mitmproxy/src/lib/interceptor/impl/req/cacheRequest.js","lineNumber":53,"sourceCode":"}\n\n// 获取 lastModifiedTime 的方法\nfunction getLastModifiedTimeFromIfModifiedSince (rOptions, log) {\n  // 获取 If-Modified-Since 用于判断是否命中缓存\n  const lastModified = rOptions.headers['if-modified-since']\n  if (lastModified == null || lastModified.length === 0) {\n    return null // 没有lastModified，返回null\n  }\n\n  // 优先尝试作为纯数字时间戳（毫秒）解析，避免 new Date() 将其当作无效日期而返回 NaN\n  if (PURE_NUMBER_RE.test(lastModified)) {\n    return Number.parseInt(lastModified, 10)\n  }\n\n  // 再尝试作为日期字符串解析\n  const time = new Date(lastModified).getTime()\n  if (Number.isNaN(time)) {\n    log.warn(`cache intercept: 解析 if-modified-since 失败: '${lastModified}'`)\n    return null\n  }\n\n  return time\n}\n\nmodule.exports = {\n  name: 'cacheRequest',\n  priority: 104,\n  requestIntercept (context, interceptOpt, req, res, ssl, next) {\n    const { rOptions, log } = context\n\n    if (rOptions.method !== 'GET') {\n      return // 非GET请求，不拦截\n    }\n\n    // 获取 Cache-Control 用于判断是否禁用缓存\n    const cacheControl = rOptions.headers['cache-control']","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/docmirror/dev-sidecar/blob/7710cd56cce760c708f30b01d2d4056eb8c402d5/packages/mitmproxy/src/lib/interceptor/impl/req/cacheRequest.js#L35-L71","documentation":"The cache interceptor reads the request's `if-modified-since` header to compare against a cached resource's Last-Modified. If the header value can be parsed neither as a number (epoch) nor as a date string, it logs this warning and returns null, so conditional-request handling is skipped and the response is treated without cache revalidation.","triggerScenarios":"An HTTP client sends an `If-Modified-Since` header with a malformed value (non-numeric, non-HTTP-date, e.g. 'unknown', '0', partial timestamp) and the request goes through the cache interceptor.","commonSituations":"Custom scripts/HTTP clients hand-crafting the header; proxies upstream corrupting header values; tests sending placeholder values; locale-formatted dates not conforming to RFC 7232 IMF-fixdate.","solutions":["Fix the client to send a proper RFC 7232 date (e.g. 'Wed, 21 Oct 2015 07:28:00 GMT') or an epoch number.","Remove the `if-modified-since` header if the client cannot produce a valid value — a plain GET will still work, just uncached.","If you control a proxying layer, normalize or strip malformed If-Modified-Since headers before they reach dev-sidecar."],"exampleFix":"// before\nheaders['If-Modified-Since'] = new Date().toLocaleString()\n// after\nheaders['If-Modified-Since'] = new Date().toUTCString()","handlingStrategy":"validation","validationCode":"function isValidIfModifiedSince(v) {\n  if (v == null) return false\n  if (!Number.isNaN(Number.parseInt(v, 10))) return true\n  return !Number.isNaN(new Date(v).getTime())\n}\n// call before sending the header","typeGuard":"const isHttpDate = (v) => typeof v === 'string' && /^([A-Za-z]{3},\\s\\d{2}\\s[A-Za-z]{3}\\s\\d{4}\\s\\d{2}:\\d{2}:\\d{2}\\sGMT|\\d+)$/.test(v)","tryCatchPattern":null,"preventionTips":["Always send If-Modified-Since via new Date(x).toUTCString()","Strip unknown cache headers from hand-built HTTP clients","Add a unit test that round-trips your header value through Date parsing"],"tags":["cache","http-headers","if-modified-since","parsing"],"backgroundTag":"malformed-http-header","analyzedSha":"7710cd56cce760c708f30b01d2d4056eb8c402d5","analyzedAt":"2026-08-31T22:07:07.234Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}