Search code examples
javascriptnode.jsexpresscloudflarecloudflare-workers

How do I properly configure my Cloudflare Worker to save my sent object in Cloudflare's KV (storage)?


I am trying to save a new post on my blog as JS Object to Cloudflare's KV.

I wrote this Cloudflare's Worker code to respond to 'POST' methods.

const setCache = (key, data) => name_data.put(key, data)
const getCache = key => name_data.get(key)

async function Create(request) {
  const body = await request.text()
  const dataKey = `posts`
  const headers = {
    Allow: 'OPTIONS, GET, HEAD, POST',
    'Access-Control-Allow-Origin': '*',
    'Content-type': 'application/json',
  }
  try {
    // JSON.parse(body)
    await setData(dataKey, body)
    return new Response(body, { status: 200, headers: headers })
  } catch (err) {
    return new Response(err, { status: 500, headers: headers })
  }
}

export default Create

Here is the fetch request from my frontend:

  const onSavePostClicked = async () => {
    if (canSave) {
      const data = { title, content, author, id: nanoid() };

      fetch('https://serverless-api.mySpace.workers.dev/api/add', {
        method: 'POST',
        headers: {
          // 'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      })
        .then((response) => response)
        .then((data) => {
          console.log('Success:', data);
          setTitle('');
          setContent('');
          setAuthor('');
        })
        .catch((error) => {
          console.error('Error:', error);
        });
    }
  };

Nothing gets added to array 'posts' in my Cloudflare's namespace/KV. I think it has something with the types of the data. I had to use this:

const body = await request.text()

because I don't know how to handle preflight requests.

When I hit save, this is what I get in my Chrome's console.

POST https://serverless-api.name.workers.dev/api/add 500

And this is what I get in Cloudflare's Worker log:

"outcome": "ok",
  "scriptName": null,
  "exceptions": [],
  "logs": [],
  "eventTimestamp": 1637022226250,
  "event": {
    "request": {
      "url": "https://serverless-api.name.workers.dev/api/add",
      "method": "POST",
      "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip",
        "accept-language": "en-US",
        "cf-connecting-ip": "",
        "cf-ipcountry": "US",
        "cf-ray": "",
        "cf-visitor": "{\"scheme\":\"https\"}",
        "connection": "Keep-Alive",
        "content-length": "87",
        "content-type": "text/plain;charset=UTF-8",
        "host": "serverless-api.name.workers.dev",
        "origin": "http://localhost:3000",
        "referer": "http://localhost:3000/",
        "sec-ch-ua": "\"Google Chrome\";v=\"95\", \"Chromium\";v=\"95\", \";Not A Brand\";v=\"99\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"macOS\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "cross-site",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36",
        "x-forwarded-proto": "https",
        "x-real-ip": ""
      },
      "cf": {
        "longitude": "",
        "latitude": "",
        "tlsCipher": "",
        "continent": "NA",
        "asn": 7922,
        "clientAcceptEncoding": "gzip, deflate, br",
        "country": "US",
        "tlsClientAuth": {
          "certIssuerDNLegacy": "",
          "certIssuerSKI": "",
          "certSubjectDNRFC2253": "",
          "certSubjectDNLegacy": "",
          "certFingerprintSHA256": "",
          "certNotBefore": "",
          "certSKI": "",
          "certSerial": "",
          "certIssuerDN": "",
          "certVerified": "NONE",
          "certNotAfter": "",
          "certSubjectDN": "",
          "certPresented": "0",
          "certRevoked": "0",
          "certIssuerSerial": "",
          "certIssuerDNRFC2253": "",
          "certFingerprintSHA1": ""
        },
        "tlsVersion": "TLSv1.3",
        "edgeRequestKeepAliveStatus": 1,
        "requestPriority": "",
        "httpProtocol": "HTTP/3",

      }
    }
  },
  "id": 0
}

Solution

  • Your method to save KV data is defined with name setCache but in your handler you are attempting to call setData seems like the issue?

    Also, for preflight requests, should just be a matter of returning early / skipping save when an incoming OPTIONS request is made (returning the correct CORS headers).