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

使用React、Node、Express解决Marea Tide API未授权调用问题

解决Marea Tide API代理后端401未授权错误

我计划开发一款根据经纬度返回潮汐数据的应用,使用Marea Tide API实现。最初前端直接调用API时遭遇CORS错误,于是搭建Express后端用来隐藏API密钥并解决CORS问题,但访问localhost:8000/tides时始终返回401未授权错误。

原Express代码

const PORT = 8000;
const express = require('express');
const cors = require('cors');

const axios = require('axios');
const { application, json } = require('express');
require('dotenv').config



const backend = express()

backend.listen(PORT, () => console.log(`Tide backend is working on PORT:${PORT}`))

backend.get('/tides', (req, res, next) => {
    const url = 'https://api.marea.ooo/v2/tides';
    const options = {
        params: {
            duration: 1440,
            interval: 60,
            latitude: 36.888,
            longitude: -76.100,
        }
    };
    const config = {
        headers: {
            'x-marea-api-token': process.env.MareaToken,

        }
    };
    
    axios.get(url, options, config)
        .then(response => {console.log(response)})
        .catch(err => console.log(err))
});

终端错误信息

[nodemon] starting `node backend.js`
Tide backend is working on PORT:8000
[AxiosError: Request failed with status code 401] {
  code: 'ERR_BAD_REQUEST',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function] },
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'User-Agent': 'axios/0.27.2'
    },
    params: {
      duration: 1440,
      interval: 60,
      latitude: 36.888,
      longitude: -76.1
    },
    method: 'get',
    url: 'https://api.marea.ooo/v2/tides',
    data: undefined
  },
  // 省略冗长的请求/响应详情
  response: {
    status: 401,
    statusText: 'Unauthorized',
    data: { status: 401, error: 'Unauthorized' }
  }
}

错误原因分析

  1. dotenv未初始化:require('dotenv').config缺少括号,导致.env文件中的API密钥未被加载,process.env.MareaToken为undefined,API验证失败。
  2. Axios参数格式错误:Axios的get方法仅接受两个参数(URL和配置对象),你将参数和请求头拆分为两个对象传递,导致授权头根本没被发送(从错误日志的请求头中可看到没有x-marea-api-token字段)。
  3. 未启用CORS中间件:虽然引入了cors包,但未在Express中注册,前端调用后端接口仍可能触发CORS问题。
  4. 后端未返回数据:当前代码仅在控制台打印API响应,未将数据返回给前端请求。

修复后的完整代码

const PORT = 8000;
const express = require('express');
const cors = require('cors');
const axios = require('axios');
require('dotenv').config(); // 补全括号初始化dotenv

const backend = express();

// 启用CORS中间件,解决跨域问题
backend.use(cors());

backend.listen(PORT, () => console.log(`Tide backend is working on PORT:${PORT}`));

backend.get('/tides', async (req, res) => {
    try {
        const url = 'https://api.marea.ooo/v2/tides';
        // 将参数和请求头合并到同一个配置对象中
        const config = {
            params: {
                duration: 1440,
                interval: 60,
                latitude: 36.888,
                longitude: -76.100,
            },
            headers: {
                'x-marea-api-token': process.env.MareaToken,
            }
        };
        
        const response = await axios.get(url, config);
        // 将API数据返回给前端
        res.json(response.data);
    } catch (err) {
        console.error(err);
        // 将错误信息返回给前端,便于调试
        res.status(err.response?.status || 500).json(err.response?.data || { error: '服务器错误' });
    }
});

额外验证步骤

  1. 确保.env文件与后端代码在同一目录,内容格式正确:
MareaToken=你的实际API密钥
  1. 安装所有依赖:npm install express cors axios dotenv
  2. 重启后端服务后,再次访问localhost:8000/tides测试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 07:06:31