【问题标题】:Netlify function: GitHub API proxy request fails with `error decoding lambda response: json`Netlify 函数:GitHub API 代理请求失败,错误解码 lambda 响应:json
【发布时间】:2021-10-18 22:01:35
【问题描述】:

此 Netlify 函数应作为 example.com/.netlify/functions/github 上的端点运行,并应代理来自我的网站的获取请求,访问 GitHub API 并将数据发送回网站。

据我了解,我可以使用 GET 从 GitHub API 获取数据而无需身份验证。直接在浏览器中点击他们的 API 有效:https://api.github.com/orgs/github/repos?per_page=2(也适用于 Postman)。

数据是一个对象数组,其中每个对象都是一个存储库。

在过去的几年中,Netlify 函数(在 AWS lambda 上运行)出现了多个问题,导致出现类似于我的错误消息,所以我很困惑这是我的代码中的错误还是奇怪的东西站在他们这边。

首先,根据 Netlify 管理控制台,代理功能运行无误。在support article 中,Netlify 要求将结果返回为JSON.stringify(),所以我在这里遵循该约定:


const fetch = require('node-fetch')
const url = 'https://api.github.com/orgs/github/repos?per_page=2'

const optionsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'Content-Type'
}

const fetchHeaders = {
  'Content-Type': 'application/json',
  'Host': 'api.github.com',
  'Accept': 'application/vnd.github.v3+json',
  'Accept-Encoding': 'gzip, deflate, br'
}

exports.handler = async (event, context) => {
  if (event.httpMethod === 'OPTIONS') {
    return {
      'statusCode': '200',
      'headers': optionsHeaders,
    }

  } else {

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: fetchHeaders
      })

      const data = await response.json()
      console.log(JSON.stringify({ data }))

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

    } catch (err) {
      console.log(err)
    }
  }
}

点击https://example.com/.netlify/functions/github 的客户端获取。 URL 正确,函数执行(在 Netlify 管理面板中验证):

const repos = document.querySelectorAll('.repo')

if (repos && repos.length >= 1) {
  const getRepos = async (url) => {
    try {
      const response = await fetch(url, {
        method: "GET",
        mode: "no-cors"
      })
      
      const res = await response.text() 
      // assuming res is now _text_ as per `JSON.stringify` but neither 
      // that nor `.json()` work

      console.log(res[0].name)
      return res[0].name

    } catch(err) {
      console.log(err)
    }
  }

  const repoName = getRepo('https://example.com/.netlify/functions/github')
  
  repos.forEach((el) => {
    el.innerText = repoName
  })
}

不是 100% 确定此错误消息的来源,它可能不是 console.log(err) 尽管它显示在浏览器控制台中,因为错误代码是 502 并且错误也是直接显示在 Postman 的响应正文中。

error decoding lambda response: error decoding lambda response: json: cannot unmarshal
string into Go value of type struct { StatusCode int "json:\"statusCode\""; Headers
 map[string]interface {} "json:\"headers\""; MultiValueHeaders map[string][]interface {}
 "json:\"multiValueHeaders\""; Body string "json:\"body\""; IsBase64Encoded bool 
"json:\"isBase64Encoded,omitempty\""; Metadata *functions.Metadata 
"json:\"metadata,omitempty\"" }

没有找到任何关于这个问题的明确信息,请各位大神赐教?

【问题讨论】:

    标签: javascript node.js proxy netlify-function


    【解决方案1】:

    唯一不符合架构的响应是预检请求。从错误消息中,我假设您需要更改:

    'statusCode': '200',
    

    'statusCode': 200, // StatusCode int
    

    更好的是,因为没有内容,您可能想改用204。 如果这还不够,我可能还想在其中包含正文,因为它似乎不是可选的:

        return {
          'statusCode': 204,
          'headers': optionsHeaders,
          'body': ''
        }
    

    【讨论】:

    • 太棒了,这就是那里的错误,只需删除单引号就足够了。非常感谢。添加这些是因为我在某处阅读了一条评论,该评论说标题中的所有内容都必须始终用引号引起来。我现在在 Postman 中得到正确的结果作为字符串 (JSON.stringified() "Name of Repo"),但我无法在前端解析和使用它。 const res = await response.text() 使 res 成为一个空字符串。 res.json() 当然也会报错。有什么想法吗?
    • 需要在 fetch 标头中添加 `'Access-Control-Allow-Origin': '*',` 以获取结果(否则它仍然是“不透明的响应”)。
    猜你喜欢
    • 1970-01-01
    • 2018-09-03
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多