CloudFlare Workers - проверка файлов cookie, добавление заголовков, установка файлов cookie

Я хочу динамически добавлять заголовки http ТОЛЬКО для работников CloudFlare впервые посетителям. Например, эти заголовки:

Link: </path/to/file.css>; rel=preload; as=style; nopush
Link: </path/to/script.js>; rel=preload; as=script; nopush

Итак, мне нужно следующее, через JavaScript, в CloudFlare Workers:

  1. Проверьте, существует ли определенный файл cookie на стороне клиента.
  2. Если cookie не существует, добавьте http-заголовки, а затем установите этот конкретный cookie.
  3. Если cookie существует, ничего не делайте.

Вы можете поиграть с кодом здесь.

Вот общий пример (с использованием cookie и заголовков) из блога CF:

// A Service Worker which skips cache if the request contains
// a cookie.
addEventListener('fetch', event => {
  let request = event.request
  if (request.headers.has('Cookie')) {
    // Cookie present. Add Cache-Control: no-cache.
    let newHeaders = new Headers(request.headers)
    newHeaders.set('Cache-Control', 'no-cache')
    event.respondWith(fetch(request, {headers: newHeaders}))
  }

  // Use default behavior.
  return
})

2 ответа

Решение

Вот Cloudflare Worker, который реализует то, что вы описываете:

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

async function handle(request) {
  // Check for cookie.
  let cookies = request.headers.get('Cookie') || ""
  if (cookies.includes("returning=true")) {
    // User has been here before. Just pass request through.
    return fetch(request)
  }

  // Forward request to origin, get response.
  let response = await fetch(request)

  // Copy Response object so that we can edit headers.
  response = new Response(response.body, response)

  // Add headers.
  response.headers.append("Link",
      "</path/to/file.css>; rel=preload; as=style; nopush")
  response.headers.append("Link",
      "</path/to/script.js>; rel=preload; as=script; nopush")

  // Set cookie so that we don't add the headers
  // next time.
  response.headers.set("Set-Cookie", "returning=true")

  // Return on to client.
  return response
}

Мне удалось изменить работника и предоставить решение, где Cache-Control Заголовок удаляется, если пользователь прокомментировал сайт.

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

async function addHeaders(request) {
    // Forward request to origin, get response.
    let response = await fetch(request)

    if (response.headers.has("Content-Type") && 
        !response.headers.get("Content-Type").includes("text/html")) {
        // File is not text/html. Pass request through.
        return fetch(request)
    }

    // Copy Response object so that we can edit headers.
    response = new Response(response.body, response)

    // Check for cookie.
    let cookies = request.headers.get('Cookie') || ""
    if (cookies.includes("returning=true")) {

        if (cookies.includes("comment_") && response.headers.has("Cache-Control")) {
            // User has commented. Delete "cache-control" header.
            response.headers.delete("Cache-Control")

            // Return on to client.
            return response
        }

        // User has been here before but has not commented.
        // Just pass request through.
        return fetch(request)
    }

    // Add headers.
    response.headers.set("Link", 
        "</path/to/file.css>; rel=preload; as=style; nopush")
    response.headers.append("Link", 
        "</path/to/script.js>; rel=preload; as=script; nopush")

    // Set cookie so that we don't add the headers next time.
    response.headers.set("Set-Cookie", "returning=true")

    // Return on to client.
    return response
}

Однако, если вы пытаетесь удалить заголовок, который установлен Cloudflare в первую очередь (в данном случае Cache-Control) вы столкнетесь с неизвестной ошибкой 1101, которая сделает ваш сайт недоступным. Также вы не можете изменить заголовок, установленный Cloudflare. Очевидно, вы можете ТОЛЬКО манипулировать заголовками, установленными по происхождению, и в конечном итоге добавлять новые заголовки.

Другие вопросы по тегам