【问题标题】:What are cloudflare KV preview_ids and how to get one?什么是 cloudflare KV preview_ids 以及如何获得?
【发布时间】:2020-08-09 23:24:46
【问题描述】:

我有一个关注者wrangler.toml。当我想使用devpreview(例如npx wrangler devnpx wrangler preview)时,管理员要求将preview_id 添加到KV 命名空间。这是现有 KV 命名空间的标识符吗?

我在 Cloudflare Workers GH 中看到https://github.com/cloudflare/wrangler/issues/1458 有一张票,告诉我们应该澄清这一点,但票已关闭并添加了一条错误消息

要预览具有 KV 命名空间的工作器,您必须在配置文件中为要预览的每个 KV 命名空间指定一个 preview_id。"

这就是我来这里的原因。 :)

至于更大的上下文,如果有人能澄清一下,我会非常高兴:我看到如果我给出一个现有命名空间的值,我可以预览并且我看到在 Cloudflare 中生成了一个 __some-worker-dev-1234-workers_sites_assets_preview 类型的 KV 命名空间。这与 preview_id 中使用的标识符指向的 KV 命名空间具有不同的标识符,而我在 preview_id 中使用的标识符指向的 KV 命名空间为空。为什么提供现有 KV 命名空间的标识符会删除错误消息、部署资产并允许预览,但实际的 KV 命名空间为空并创建了一个新命名空间?

kv-asset-handler 如何知道查看这个生成的命名空间以检索资产?

我目前正在对我的站点使用默认生成的 Cloudare Worker 进行测试,我想知道我是否误解了某些内容,或者是否在预览/将站点命名空间发布到 scipt 期间捆绑了一些机制。

如果有一些带有自动映射的随机机制,那么是否可以让每个开发者都可以拥有自己的私有预览 KV 命名空间?

type = "javascript"
name = "some-worker-dev-1234"
account_id = "<id>"
workers_dev = true

kv_namespaces = [
  { binding = "site_data", id = "<test-site-id>" }
]

[site]
# The location for the site.
bucket = "./dist"

# The entry directory for the package.json that contains 
# main field for the file name of the compiled worker file in "main" field.
entry-point = ""

[env.production]
name = "some-worker-1234"
zone_id = "<zone-id>"
routes = [
  "http://<site>/*",
  "https://www.<site>/*"
]

# kv_namespaces = [
#  { binding = "site_data", id = "<production-site-id>" }
# ]

import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'

/**
 * The DEBUG flag will do two things that help during development:
 * 1. we will skip caching on the edge, which makes it easier to
 *    debug.
 * 2. we will return an error message on exception in your Response rather
 *    than the default 404.html page.
 */
const DEBUG = false

addEventListener('fetch', event => {
  try {
    event.respondWith(handleEvent(event))
  } catch (e) {
    if (DEBUG) {
      return event.respondWith(
        new Response(e.message || e.toString(), {
          status: 500,
        }),
      )
    }
    event.respondWith(new Response('Internal Error', { status: 500 }))
  }
})

async function handleEvent(event) {
  const url = new URL(event.request.url)
  let options = {}

  /**
   * You can add custom logic to how we fetch your assets
   * by configuring the function `mapRequestToAsset`
   */
  // options.mapRequestToAsset = handlePrefix(/^\/docs/)

  try {
    if (DEBUG) {
      // customize caching
      options.cacheControl = {
        bypassCache: true,
      }
    }

    const page = await getAssetFromKV(event, options)

    // allow headers to be altered
    const response = new Response(page.body, page)

    response.headers.set('X-XSS-Protection', '1; mode=block')
    response.headers.set('X-Content-Type-Options', 'nosniff')
    response.headers.set('X-Frame-Options', 'DENY')
    response.headers.set('Referrer-Policy', 'unsafe-url')
    response.headers.set('Feature-Policy', 'none')

    return response

  } catch (e) {
    // if an error is thrown try to serve the asset at 404.html
    if (!DEBUG) {
      try {
        let notFoundResponse = await getAssetFromKV(event, {
          mapRequestToAsset: req => new Request(`${new URL(req.url).origin}/404.html`, req),
        })

        return new Response(notFoundResponse.body, { ...notFoundResponse, status: 404 })
      } catch (e) {}
    }

    return new Response(e.message || e.toString(), { status: 500 })
  }
}

/**
 * Here's one example of how to modify a request to
 * remove a specific prefix, in this case `/docs` from
 * the url. This can be useful if you are deploying to a
 * route on a zone, or if you only want your static content
 * to exist at a specific path.
 */
function handlePrefix(prefix) {
  return request => {
    // compute the default (e.g. / -> index.html)
    let defaultAssetKey = mapRequestToAsset(request)
    let url = new URL(defaultAssetKey.url)

    // strip the prefix from the path for lookup
    url.pathname = url.pathname.replace(prefix, '/')

    // inherit all other props from the default request
    return new Request(url.toString(), defaultAssetKey)
  }
}

【问题讨论】:

    标签: cloudflare cloudflare-workers


    【解决方案1】:

    如果格式不明显(对我来说不是),这里是来自docs 的示例配置块,其中为几个 KV 命名空间指定了 preview_id:

    kv_namespaces = [  
      { binding = "FOO", id = "0f2ac74b498b48028cb68387c421e279", preview_id = "6a1ddb03f3ec250963f0a1e46820076f" },
      { binding = "BAR", id = "068c101e168d03c65bddf4ba75150fb0", preview_id = "fb69528dbc7336525313f2e8c3b17db0" }
    ]
    

    您可以在仪表板的 Workers KV 部分或使用 Wrangler CLI 生成新的命名空间 ID: wrangler kv:namespace create "SOME_NAMESPACE" --preview

    【讨论】:

    • 好点。我认为文档并没有很清楚地说明“开发”和“预览”模式之间的区别以及它与 KV 命名空间的关系。这就是我最初对似乎具有不相关 ID 的示例片段感到困惑的原因。我认为文档应该仍然更清晰,并且还需要注意在 package.json 中需要有 main,以防使用 Rollup (=JavaScript) 等等。
    • 我意识到我给出的 wrangler 命令有效,但并不是该实用程序的真正用途。修好了。
    • 值得注意的是:该命令中的命名空间需要与已经存在的命名空间相同。即 wrangler.toml 文件中行上的“绑定”值。
    【解决方案2】:

    此答案适用于 Wrangler >= 1.10.0

    的版本

    wrangler 要求将 preview_id 添加到 KV 命名空间。这是现有 KV 命名空间的标识符吗?

    是的!预览命名空间有不同标识符的原因是,当使用wrangler devwrangler preview 进行开发时,您不会意外地使用可能有错误或不兼容的代码对现有生产数据进行更改。您可以在大多数 wrangler kv 命令中添加 --preview 标志,以与您的预览命名空间进行交互。


    对于您这里的情况,实际上发生了一些事情。

    1. 您正在使用工人站点
    2. 您在wrangler.toml 中定义了一个 KV 命名空间

    Workers Sites 将自动为您在其上运行 wrangler publish 的每个环境配置一个生产命名空间,并为您在其上运行 wrangler devwrangler preview 的每个环境配置一个预览命名空间。如果您只需要 Workers Sites,那么根本不需要在清单中指定 kv-namepsaces 表。该表适用于您可能希望从中读取数据或向其中写入数据的其他 KV 命名空间。如果这是你需要的,你需要配置你自己的命名空间,如果你想使用wrangler.toml,你需要配置你自己的命名空间并添加wrangler.toml,如果你想使用@,preview_id(应该不同) 987654334@或wrangler preview

    【讨论】:

    • 这是有道理的。您知道(当前)自动生成的 Worker 脚本如何知道如何从预览命名空间中获取数据吗?我看到getAssetFromKV 等。或者这是否是单独问题的情况,我也想知道......我想知道这个单独问题的原因是因为这个原因有点令人困惑(并且在文档中命名空间 ID是不知道它来自哪里的东西)。
    猜你喜欢
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 2023-02-24
    • 2021-10-26
    • 2014-01-22
    • 2014-03-10
    • 2011-08-29
    • 1970-01-01
    相关资源
    最近更新 更多