使用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' } } }
错误原因分析
- dotenv未初始化:
require('dotenv').config缺少括号,导致.env文件中的API密钥未被加载,process.env.MareaToken为undefined,API验证失败。 - Axios参数格式错误:Axios的
get方法仅接受两个参数(URL和配置对象),你将参数和请求头拆分为两个对象传递,导致授权头根本没被发送(从错误日志的请求头中可看到没有x-marea-api-token字段)。 - 未启用CORS中间件:虽然引入了cors包,但未在Express中注册,前端调用后端接口仍可能触发CORS问题。
- 后端未返回数据:当前代码仅在控制台打印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: '服务器错误' }); } });
额外验证步骤
- 确保
.env文件与后端代码在同一目录,内容格式正确:
MareaToken=你的实际API密钥
- 安装所有依赖:
npm install express cors axios dotenv - 重启后端服务后,再次访问
localhost:8000/tides测试
内容的提问来源于stack exchange,提问作者jpa317
相关产品推荐
相关产品推荐

