如何将curl命令转为JavaScript fetch?React请求报错解决
问题:React项目中转换curl为fetch时出现"Invalid name"错误
我正在开发一个React项目并调用某API,该API文档仅提供以下curl命令:
#!/bin/bash apiKey="yourApiKey" secret="yourSecret" curl -i \ -X GET \ -H 'Accept:application/json' \ -H 'Api-key:'$apiKey'' \ -H 'X-Signature:'$(echo -n ${apiKey}${secret}$(date +%s)|sha256sum|awk '{ print $1}')'' \ https://example.com
我尝试将其转换为JavaScript fetch代码:
const sec = Date.now() / 1000 + ""; const myString = "someApiKey" + "apiSecret" + sec; const bitArr = sjcl.hash.sha256.hash(myString); const hash = sjcl.codec.hex.fromBits(bitArr); useEffect(() => { fetch( "https://cors-anywhere.herokuapp.com/https://example.com", { method: "GET", headers: { Accept: "application/json", "content/type": "application/json", "Api-key":'someApiKey', 'X-Signature': hash }, }) .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => console.log(err)); }, []);
但执行时出现错误:
TypeError: Failed to execute 'fetch' on 'Window': Invalid name
错误原因与修正方案
1. 直接解决报错:修复非法请求头
你在headers里写的"content/type"是非法的请求头名称,正确的Content-Type头格式是"Content-Type",而且GET请求不需要设置这个头(GET请求没有请求体,无需指定内容类型),删掉这个错误的头就能立刻解决"Invalid name"问题。
2. 其他需要对齐curl逻辑的细节
- 时间戳格式统一:curl中
date +%s生成的是整数秒级时间戳,而Date.now()/1000会产生小数,需要取整保证签名一致:const sec = Math.floor(Date.now() / 1000).toString(); - 完善useEffect依赖:当前依赖数组为空,会导致useEffect只执行一次,且可能使用过期的签名值,需要把
hash、sec和apiKey加入依赖数组:useEffect(() => { // fetch逻辑 }, [hash, sec, apiKey]); - 跨域代理优化:开发环境建议使用React官方代理配置(在
package.json中添加"proxy": "https://example.com"),避免依赖第三方cors-anywhere服务。
修正后的完整代码
import { useEffect } from 'react'; import sjcl from 'sjcl'; const YourComponent = () => { const apiKey = "someApiKey"; const apiSecret = "apiSecret"; const sec = Math.floor(Date.now() / 1000).toString(); const myString = apiKey + apiSecret + sec; const bitArr = sjcl.hash.sha256.hash(myString); const hash = sjcl.codec.hex.fromBits(bitArr); useEffect(() => { fetch("https://example.com", { // 配置代理后直接用原API地址 method: "GET", headers: { Accept: "application/json", "Api-key": apiKey, "X-Signature": hash }, }) .then((res) => { if (!res.ok) throw new Error(`请求失败,状态码:${res.status}`); return res.json(); }) .then((data) => console.log(data)) .catch((err) => console.error(err)); }, [hash, sec, apiKey]); return <div>你的组件内容</div>; }; export default YourComponent;
内容的提问来源于stack exchange,提问作者droppre
相关产品推荐
相关产品推荐

