在 Netlify 函数中获取简单 Fetch 的问题

Issue getting simple Fetch working in Netlify Functions

我一直在参加 Netlify 函数的研讨会,并且偶然发现了一个简单的 Fetch 响应。当 运行 样本位于: https://github.com/DavidWells/netlify-functions-workshop/blob/master/lessons-code-complete/use-cases/5-fetching-data/functions/node-fetch/node-fetch.js

const fetch = require('node-fetch')

const API_ENDPOINT = 'https://cat-fact.herokuapp.com/facts'

exports.handler = async (event, context) => {   let response   
  try {
    response = await fetch(API_ENDPOINT)
    // handle response   
  } catch (err) {
    return {
      statusCode: err.statusCode || 500,
      body: JSON.stringify({
        error: err.message
      })
  }   }

  return {
    statusCode: 200,
    body: JSON.stringify({
      data: response
    })   } }

但我只收到以下回复:

{"data":{"size":0,"timeout":0}}

构建过程运行良好,我尝试了其他端点,但都给出了相同的结果。

handle response 行,您需要等待 json 结果:

response = await response.json();

查看 MDN article for Using Fetch 了解更多详情。

最后我切换到 Axios 库,第一次成功了:

const axios = require('axios')

const API_ENDPOINT = 'https://jsonplaceholder.typicode.com/todos/1'

exports.handler = async (event, context) => {
  let response
  try {
    response = await axios.get(API_ENDPOINT)
  } catch (err) {
    return {
      statusCode: err.statusCode || 500,
      body: JSON.stringify({
        error: err.message
      })
    }
  }

  return {
    statusCode: 200,
    body: JSON.stringify({
      data: response.data
    })
  }
}

这是使用 node-fetch 和回调的原始代码的工作版本。

// import fetch from 'node-fetch';
const fetch = require('node-fetch')

const checkStatus = (res) => {
  if (res.ok) { // res.status >= 200 && res.status < 300
      return res.json()
  } else {
      throw new Error(res.statusText);
  }
}

exports.handler = async function(event, context, callback) {
  try {
    const response = await fetch('https://cat-fact.herokuapp.com/facts')
    const data = await checkStatus(response)
    callback(null, {
      statusCode: 200,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    })
  } catch (error) {
    callback(error)
  }
}

注意: Netlify 函数只是 AWS 函数,您可以阅读 AWS Lambda Function Handler in the AWS docs

For async functions, you return a response, error, or promise to the runtime instead of using callback.

我喜欢使用文档中推荐的方法,因为它受支持并保存 non-async 函数的回调。

这是一个工作版本,它返回一个 promise 给异步函数。

// import fetch from 'node-fetch';
const fetch = require('node-fetch')

exports.handler = async (event, context) => {
  return new Promise((resolve, reject) => {
    fetch('https://cat-fact.herokuapp.com/facts')
    .then(res => {
      if (res.ok) { // res.status >= 200 && res.status < 300
        return res.json();
      } else {
        resolve({ statusCode: res.status || 500, body: res.statusText })
      };
    })
    .then(data =>{
      const response = {
        statusCode: 200,
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(data)
      }
      resolve(response);
    })
    .catch(err => {
      console.log(err)
      resolve({ statusCode: err.statusCode || 500, body: err.message })
    })
  })
}

这只是一个例子,还有其他方法可以处理错误,但这个例子解决了响应而不是拒绝。它没有作为生产示例进行测试,但可以让您了解其中的区别。

Here are some examples of Netlify functions.