【问题标题】:Cloudflare Worker Cache Put Mobile Not WorkingCloudflare Worker Cache Put Mobile 不工作
【发布时间】:2021-01-13 11:13:23
【问题描述】:

以下是在 Cloudflare Worker 中运行的代码。我正在使用它来按设备类型代理请求缓存。用户将访问 example.com/blog,Worker 会将请求代理到 blog.example.com - 这一切正常。完成此操作后,我将使用 Cache API 来缓存特定于设备的页面版本。问题是从移动设备请求的 url 不会从缓存中获得服务。可以是真正的移动设备,也可以是使用 Chrome 的开发工具。

x-key 标头包含正确的 url 'https://m.www.example.com/blog/',但是 cf-cache-status 标头在每个请求中都包含 DYNAMIC。如果我改用台式电脑或平板电脑,x-key 是“https://d.www.example.com/blog/”或“https://t.www.example.com/blog/”,而cf-cache-status 标头在第一次请求后包含 HIT。

我假设如果 cache.put 失败,什么都不会返回,或者我会看到错误消息?

我只是看不出设备的类型会如何产生影响...任何人都可以看到代码的问题吗?

下面是我正在使用的代码:

const originUrl = 'https://blog.example.com/'
const publicUrl = 'https://www.example.com/blog/'
const blockedPaths = ['wp-admin', 'wp-login', 'wp-json']

addEventListener('fetch', event => {  
    return event.respondWith(handleRequest(event))
})

async function handleRequest(e) {
  if (new RegExp(blockedPaths.join('|')).test(e.request.url)) {
      return Response.redirect(publicUrl, 302)
  }

  let cache = caches.default
  let deviceType = 'd'
  let userAgent = e.request.headers.get('User-Agent') || ''
  let url = new URL(e.request.url)

  if(isMobileAgent(userAgent)) {
    deviceType = 'm'
  } else if(isTabletAgent(userAgent)) {
    deviceType = 't'
  }
  
  let cacheKey = `${url.protocol}//${deviceType}.${url.hostname}${url.pathname}`
  let response = await cache.match(cacheKey)
  
  if(!response) {
    response = await fetch(buildOriginUrl(e.request.url), e.request)
    response = new Response(response.body, response)
    response = urlRewriter.transform(response)

    response.headers.delete('vary')
    response.headers.delete('pragma')
    response.headers.delete('expires')
    response.headers.delete('last-modified')

    e.waitUntil(cache.put(cacheKey, response.clone()));
  }

  response = new Response(response.body, response)
  response.headers.set('Cache-Control', 'public; max-age=604800')
  response.headers.set('x-devicetype', deviceType)
  response.headers.set('x-key', cacheKey)
  response.headers.set('x-powered-by', '')
  response.headers.delete('x-powered-by')

  return response
}

function buildOriginUrl(requestUrl) {
  if(!requestUrl){
    return
  }

  return requestUrl.replace(publicUrl, originUrl)
}

function isMobileAgent(userAgent) {
  var check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(userAgent)
  return check;
}

function isTabletAgent(userAgent) {
  var check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(userAgent)
  return check;
}

class AttributeRewriter {
  constructor(attributeName) {
    this.attributeName = attributeName
  }

  element(element) {
    const attribute = element.getAttribute(this.attributeName)
    
    if (attribute) {
      element.setAttribute(this.attributeName, attribute.replace(originUrl, publicUrl))
    }
  }
}

const urlRewriter = new HTMLRewriter().on('a', new AttributeRewriter('href')).on('img', new AttributeRewriter('src'))

我也尝试过使用:

let cache = await caches.open('example');

但这并没有什么不同

2021 年 1 月 14 日 15:40 更新

缓存请求的 HTTP 标头是:

age: 5908
cache-control: public; max-age=604800
cf-cache-status: HIT
cf-ray: 611859ce7e2f40a7-LHR
cf-request-id: 07a316750b000040a7e02aa000000001
content-encoding: br
content-type: text/html; charset=UTF-8
date: Thu, 14 Jan 2021 15:22:09 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
link: <https://www.example.com/shipping/wp-json/>; rel="https://api.w.org/", <https://www.example.com/shipping/?p=1317>; rel=shortlink
nel: {"report_to":"cf-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=HbUZpOq5ZHVhF7%2FznXlPx9iUuoLUWD5ArGot5I0dYy7fSVuvJ%2BVTS3xzM%2Fety5mZIU4K1AeptoFEUznT5IQhxO7ZIzI%2BxLxPh8JtE15P8LWppw%3D%3D"}],"group":"cf-nel","max_age":604800}
server: cloudflare
set-cookie: __cfduid=d2e0c44aa8532edfea9ad8cdeca463ff41610637729; expires=Sat, 13-Feb-21 15:22:09 GMT; path=/; domain=.example.com; HttpOnly; SameSite=Lax; Secure
vary: Accept-Encoding
x-devicetype: d
x-key: https://d.www.example.com/shipping/my-baggage-boxes/
x-pingback: https://shipping.example.com/xmlrpc.php

非缓存请求的 HTTP 标头是:

cache-control: public; max-age=604800
cf-cache-status: DYNAMIC
cf-ray: 61185ab4fe3140a7-LHR
cf-request-id: 07a3170518000040a7319c5000000001
content-encoding: br
content-type: text/html; charset=UTF-8
date: Thu, 14 Jan 2021 15:22:46 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
link: <https://www.example.com/shipping/wp-json/>; rel="https://api.w.org/", <https://www.example.com/shipping/?p=1317>; rel=shortlink
nel: {"report_to":"cf-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=qct0tHNNNSwVEkWMNCWHjKDDmdRibPMCexx10C377q6X8UxoEouyHLpMvPA7xa9jTrexW3O2CjVf4Vjq1aqNEA7Izc9wYsH71pmN3Qn9PybjmQ%3D%3D"}],"group":"cf-nel","max_age":604800}
server: cloudflare
vary: Accept-Encoding
x-devicetype: m
x-key: https://m.www.example.com/shipping/my-baggage-boxes/
x-pingback: https://shipping.example.com/xmlrpc.php

我已更新 Worker 以删除 Cache.Put 之前的变量、杂注、过期和最后修改。我仍然不明白是什么导致了这个问题。我假设没有办法获得 Put 调用的报告?

【问题讨论】:

  • 非常感谢您缩小问题范围。这很奇怪。我能想到的唯一解释可能是移动响应包含一些导致缓存决定响应不可缓存的标头,而桌面/平板电脑响应由于某种原因没有此标头。例如,Set-Cookie 标头的存在可能会导致缓存拒绝存储响应。在调用 put() 之前,您的工作人员可以尝试删除看起来可能有问题的标头。我很想知道你发现了什么。
  • @KentonVarda,这是给你的回复 - 我已经用标题的详细信息更新了问题 - 仍然不确定问题是什么

标签: cloudflare-workers


【解决方案1】:

可能存在修改缓存行为的页面规则。 你检查过吗?

【讨论】:

  • Christian,感谢您的回复 - 我检查了页面规则,并且有任何配置
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 2023-03-26
  • 2020-04-18
  • 2023-01-14
  • 1970-01-01
相关资源
最近更新 更多