在 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 })
})
})
}
这只是一个例子,还有其他方法可以处理错误,但这个例子解决了响应而不是拒绝。它没有作为生产示例进行测试,但可以让您了解其中的区别。
我一直在参加 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 })
})
})
}
这只是一个例子,还有其他方法可以处理错误,但这个例子解决了响应而不是拒绝。它没有作为生产示例进行测试,但可以让您了解其中的区别。