You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中绕过myfitnesspal登录的“启用Cookie和JavaScript”错误

问题

在Glitch环境中用Node.js调用MyFitnessPal接口时,遇到如下问题:

  • 流程验证:先通过HTTP GET获取会话Cookie,再用HTTP POST提交登录信息获取JSON数据,该流程在Postman中手动执行完全成功。
  • Node.js代码复现异常:POST请求返回403错误,提示内容为:

Enable JavaScript and cookies to continue

  • 已排除Cookie缺失问题:确认GET请求的Cookie已通过request-promise的jar: true配置自动传递给POST请求。
  • 核心疑问:
    • Postman不会运行页面JavaScript,为何能成功?难道Postman后台偷偷执行了网站的JS?
    • 浏览器访问时,首次GET请求会下载并执行大量JS,这些JS是否是完成认证的必要环节?

附上Node.js代码片段:

const rp = require("request-promise").defaults({ jar: true });

var server='https://www.myfitnesspal.com/reports/printable-diary/';
var resp={success : false};
let agent='PostmanRuntime/7.43.0'; 
var options = {
    method: 'GET',
    uri: server+request.query.uid, 
    headers: {
      'accept' : '*/*',
      'User-Agent': agent,
      "Accept-Language": "en-US,en;q=0.9",
      'Connection': 'keep-alive',
      'cache-control': 'no-cache'
    },
    query: {
      from: '2025-01-05',
      to: '2025-01-05'
    },
    resolveWithFullResponse: true
};  
rp(options) // First request gets session cookies  
    .then(function (response) {
  // prepare 2nd request to login and get data
      let options2={
        method: 'POST',
        uri: 'https://www.myfitnesspal.com/api/services/authenticate_diary_key',
        headers: {
          'accept' : '*/*',
          'User-Agent': agent,
          'Accept-Language': 'en-US,en;q=0.9',
          'cache-control': 'no-cache',
          'Referer': 'https://www.myfitnesspal.com/reports/printable-diary/'+ request.query.uid +'?from=2025-01-05&to=2025-01-05',
          'Connection': 'keep-alive'
        },  
        body: {
          "key":request.query.key,
          "show_food_diary":1,
          "show_exercise_diary":0,
          "show_food_notes":0,
          "show_exercise_notes":0,
          "username":request.query.uid,
          "from":"2025-01-05",
          "to":"2025-01-05"
        },
        resolveWithFullResponse: true,
        json: true 
      };
      return rp(options2);    
    })
    .then (function (response){
      console.log(response.headers);
      resp={success : true};
    })  
    .finally(function (){
      reply.code(200).send(resp);  
    })
    .catch(function (err) {
      // POST failed...
      console.log("ERROR!");
      console.log(err);
      reply.code(err.statusCode).send({result: 0});
    });  
分析与解决思路

为什么Postman能成功?

Postman虽不渲染页面JS,但它的请求模拟更贴近浏览器的细节行为:

  • 自动抓取隐藏验证参数:部分网站会在GET页面时生成隐藏表单字段(如CSRF token、会话标识),Postman会自动识别并在POST请求中携带这些参数,而你的Node.js代码仅传递了自定义的body参数,漏掉了这类关键验证字段。
  • 请求头完整性更高:Postman会自动补充浏览器默认的请求头(如Accept-Encoding、Origin),你的代码可能缺少这些头,导致服务器判定为非浏览器请求。
  • 会话状态完整传递:除了Cookie,Postman会保留并传递GET响应中的其他会话标识(如响应头内的token),而你的代码仅处理了Cookie。

浏览器下载的JS是否必要?

是的,这些JS大概率是完成人机验证或会话初始化的核心环节:

  • 网站可能通过JS生成额外会话参数(如动态CSRF token),并存储到Cookie或本地存储中,后续POST请求必须携带这些参数才能通过验证。
  • 部分反爬机制(如Cloudflare JS挑战)需要执行JS生成验证凭证,只有通过验证后,服务器才会接受后续请求。

修复建议

  • 抓取浏览器完整请求参数:用浏览器开发者工具监控POST请求,对比你的Node.js请求,找出遗漏的参数(如csrf_token、__RequestVerificationToken),将其加入POST的body中。
  • 补全请求头:复制浏览器的所有请求头到代码中,不要仅保留部分,尤其注意Origin、Accept-Encoding、Content-Type这类易忽略的头。
  • 改用无头浏览器:若网站存在JS验证机制,单纯HTTP请求库无法绕过,建议使用Puppeteer这类无头浏览器工具,模拟真实浏览器的完整行为(加载JS、执行验证、提交表单)。
  • 替换request-promise:request-promise已停止维护,建议改用axios或node-fetch,这些库维护更活跃,更易处理复杂请求场景。

内容的提问来源于stack exchange,提问作者Ardent837

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:40:07