UrlFetchApp与Axios请求MyFitnessPal返回结果不一致问题
问题
我用Node.js的Axios编写代码可以正常获取MyFitnessPal的饮食日记:
"use strict"; const axios = require('axios') async function getReport(username) { const foodLog = await axios({ method: 'POST', url: `https://www.myfitnesspal.com/api/services/authenticate_diary_key/${username}`, data: { from: "2023-01-20", to: "2023-01-30", show_food_diary: 1, show_exercise_diary: 1, show_food_notes: 0, show_exercise_notes: 0, key: "" } }) // do stuff with foodLog }
该请求返回的响应包含日期数组,每个日期下有餐食等信息。
但用Google Apps Script的UrlFetchApp发起完全相同的请求时,得到的是空响应:
function getReport(username) { const url = `https://www.myfitnesspal.com/api/services/authenticate_diary_key/${username}` const payload = { from: "2023-01-20", to: "2023-01-30", show_food_diary: 1, show_exercise_diary: 1, show_food_notes: 0, show_exercise_notes: 0, key: "" } const options = { payload, method: 'post' } try { const response = UrlFetchApp.fetch(url,options) console.log(response.getResponseCode()) //200 console.log(response.getContentText()) // [] } catch (error){ console.log(error) } }
请求状态码为200无错误,但响应内容是空数组。请问我遗漏了什么配置?
注:可传入公开日记且指定日期有餐食记录的MyFitnessPal用户名调用getReport()复现问题。
解决方案
问题出在UrlFetchApp的默认请求配置和Axios不同,需要调整以下几点:
强制设置请求内容类型为JSON
Axios默认会把data序列化为JSON并设置Content-Type: application/json,但UrlFetchApp如果直接传入对象作为payload,默认会用application/x-www-form-urlencoded格式发送,这会导致MyFitnessPal的API无法正确解析参数,返回空数组。修改代码,手动将payload转为JSON字符串,并设置headers:
function getReport(username) { const url = `https://www.myfitnesspal.com/api/services/authenticate_diary_key/${username}` const payload = JSON.stringify({ from: "2023-01-20", to: "2023-01-30", show_food_diary: 1, show_exercise_diary: 1, show_food_notes: 0, show_exercise_notes: 0, key: "" }) const options = { payload: payload, method: 'post', headers: { 'Content-Type': 'application/json' } } try { const response = UrlFetchApp.fetch(url,options) console.log(response.getResponseCode()) console.log(response.getContentText()) } catch (error){ console.log(error) } }添加User-Agent头(可选但推荐)
部分API会验证请求的User-Agent,Axios有默认的User-Agent,而UrlFetchApp的默认UA可能被识别为非标准客户端,添加一个常见的UA可以避免被拦截:headers: { 'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' }确认payload参数类型
确保show_food_diary等数值类型参数在JSON序列化后是数字而非字符串,直接用数字定义即可,不要加引号。
内容的提问来源于stack exchange,提问作者dankata1272
相关产品推荐
相关产品推荐

