Cloudflare Worker Headers 破坏添加到购物车按钮

Cloudflare Worker Headers breaking Add to Cart Button

经过几个小时的挖掘,我找到了为什么 Woocommerce 的“添加到购物车”按钮不再起作用的原因;我的 cloudflare 工人!完整代码如下,但问题是关于 header 负责的信息:

const response = await fetch(request)

 return new Response(html, {
        headers: response.headers

我曾尝试修改 headers,但国际样式根本不起作用。实验在这里:https://ellasbubbles.com/product/ella-shower-column-kit-for-walk-in-tub-deck-mount-faucets/。如果您在 U.S/CA 内部,则不会因为 IF 语句而看到此问题。

header 有什么问题吗?我应该以不同的方式修改它们吗?我应该以不同的方式插入 css 吗?

Cloudflare 工作人员:

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

/**
 * Fetch and log a given request object
 * @param {Request} request
 */
async function handleRequest(request) {
    const country = request.cf.country
    if (country != 'US' && country !='CA') {
    const response = await fetch(request)
    var html = await response.text()
    
    // Inject scripts
    const customScripts = '<style type="text/css">custom css here</style></body>'
    html = html.replace( /<\/body>/ , customScripts)

    // return modified response
    return new Response(html, {
        headers: response.headers
    }) 
}
}

我试过 运行 这样的代码,点击“添加到购物车”后 - 整个页面变为空白,因为点击“添加到购物车”按钮后里面什么也没有

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

/**
 * Fetch and log a given request object
 * @param {Request} request
 */
async function handleRequest(request) {
    const country = request.cf.country
    if (country != 'US' && country !='CA') {
    const response = await fetch(request)
    var html = await response.text()
    
    // return modified response
    return new Response(html, {
        headers: response.headers
    }) 
}
}

已更新(解决方案)

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

async function handleRequest(request) {
    const country = request.cf.country
    if (country != 'US' && country !='CA') {
    const response = await fetch(request)
    const type = response.headers.get("Content-Type") || "";
    if (!type.startsWith("text/html")) {
     return response;
   }

    var html = await response.text()
    
    // Inject scripts
    const customScripts = 'Styling Here'
    html = html.replace( /<\/body>/ , customScripts)

    // return modified response
    return new Response(html, {
        headers: response.headers
    })
}
}

我在这里看到了一些问题。

if (country != 'US' && country !='CA') {

如果国家是美国或加拿大,整个处理函数似乎不会运行,这意味着不会发送任何响应。

    // return modified response
    return new Response(html, {
        headers: response.headers
    }) 

在这里,您要从原始响应中复制 header,但不会复制其他属性,例如状态代码。试试这个:

    // return modified response
    return new Response(html, response)

这里,response的所有属性都会被复制过来,除了来自html.

的body

另一个问题是您正在修改 所有 个响应,即使它们不是 HTML。例如。您可能不小心修改了 JSON API 回复。更糟糕的是,如果你处理二进制文件,比如图像,那么这段代码几乎肯定会破坏它,因为它将二进制文件转换为文本。为避免这种情况,您可能需要在修改之前检查 Content-Type header,例如:

    const response = await fetch(request)
    const type = response.headers.get("Content-Type") || "";
    if (!type.startsWith("text/html")) {
      // Not HTML, don't modify.
      return response;
    }