Multiavatar API调用报net::ERR_INVALID_URL,头像无法显示求助
解决Multiavatar API请求报错net::ERR_INVALID_URL及头像无法显示问题
问题核心
使用Multiavatar API拉取随机头像并转为base64后,控制台报错net::ERR_INVALID_URL,头像无法正常渲染。
错误点排查
- URL构造错误:原代码中
api变量包含多余路径45678945,拼接随机数后生成的URL不符合Multiavatar API格式要求,导致无效请求。 - axios响应类型未配置:默认请求返回字符串,直接用
Buffer.from处理会出现编码异常,无法正确生成base64。 - Data URI格式错误:头像渲染时的
src用分号;分隔base64内容,正确格式应该用逗号,。
修复方案
- 修正API URL结构:移除
api变量中的多余路径,直接用基础域名拼接唯一标识和API密钥。 - 配置axios响应类型:设置
responseType: 'arraybuffer',确保获取二进制数据后正确转base64。 - 修复Data URI格式:将
data:image/svg+xml;base64;${avatar}改为data:image/svg+xml;base64,${avatar}。
修复后的关键代码片段
const apiKey = '3a6j4ToRdWLPyA'; const api = `https://api.multiavatar.com`; // 移除多余路径 useEffect(() => { const fetchData = async () => { const data = []; for (let i = 0; i < 4; i++) { // 配置responseType为arraybuffer,获取二进制数据 const image = await axios.get( `${api}/${Math.round(Math.random() * 1000)}?apikey=${apiKey}`, { responseType: 'arraybuffer' } ); // 从二进制数据生成base64 const base64 = Buffer.from(image.data).toString('base64'); data.push(base64); } setAvatars(data); setIsLoading(false); }; fetchData(); }, [api]);
渲染部分修正:
<img src={`data:image/svg+xml;base64,${avatar}`} // 把分号改成逗号 alt="avatar" key={avatar} onClick={() => setSelectedAvatar(index)} />
完整修复后组件代码
import React, { useState, useEffect } from 'react'; import axios from "axios"; import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; import { Buffer } from 'buffer'; import loader from "../assets/loader.gif"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { setAvatarRoute } from '../utils/APIRoutes'; const SetAvatar = () => { const apiKey = '3a6j4ToRdWLPyA'; const api = `https://api.multiavatar.com`; // 修正API地址 const navigate = useNavigate(); const [avatars, setAvatars] = useState([]); const [isLoading, setIsLoading] = useState(true); const [selectedAvatar, setSelectedAvatar] = useState(undefined); const toastOptions = { position: "bottom-right", autoClose: 8000, pauseOnHover: true, draggable: true, theme: "dark", }; useEffect(() => { const fetchData2 = async () => { if (!localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)) navigate("/login"); }; fetchData2(); }, []); // 补充空依赖数组,避免无限触发 const setProfilePicture = async () => { if (selectedAvatar === undefined) { toast.error("Please select an avatar", toastOptions); } else { const user = JSON.parse(localStorage.getItem(process.env.REACT_APP_LOCALHOST_KEY)); const { data } = await axios.post(`${setAvatarRoute}/${user._id}`, { image: avatars[selectedAvatar], }); if (data.isSet) { user.isAvatarImageSet = true; user.avatarImage = data.image; localStorage.setItem( process.env.REACT_APP_LOCALHOST_KEY, JSON.stringify(user) ); navigate("/"); } else { toast.error("Error setting avatar. Please try again.", toastOptions); } } }; useEffect(() => { const fetchData = async () => { const data = []; for (let i = 0; i < 4; i++) { const image = await axios.get( `${api}/${Math.round(Math.random() * 1000)}?apikey=${apiKey}`, { responseType: 'arraybuffer' } // 配置响应类型 ); const base64 = Buffer.from(image.data).toString('base64'); data.push(base64); } setAvatars(data); setIsLoading(false); }; fetchData(); }, [api]); return ( <> {isLoading ? ( <Container> <img src={loader} alt="loader" className='loader' /> </Container> ) : ( <Container> <div className="title-container"> <h1>Pick an Avatar as your profile picture</h1> </div> <div className="avatars"> {avatars.map((avatar, index) => { return ( <div className={`avatar ${selectedAvatar === index ? "selected" : ""}`} key={index} > <img src={`data:image/svg+xml;base64,${avatar}`} // 修正Data URI格式 alt="avatar" key={avatar} onClick={() => setSelectedAvatar(index)} /> </div> ); })} </div> <button onClick={setProfilePicture} className='submit-btn'> Set as Profile Picture </button> <ToastContainer /> </Container> )} </> ); } export default SetAvatar;
额外说明:还修复了第一个useEffect的依赖数组为空的问题,避免组件每次渲染都触发路由检查。
内容的提问来源于stack exchange,提问作者Aaryan02
相关产品推荐
相关产品推荐

