React项目调用Mapbox API批量请求地址数据异常问题
Mapbox请求URL被截断的原因及修复方案
问题背景
在React项目中,从Firebase获取数据后传入getMapboxAddresses函数生成Mapbox地理编码请求,但部分地址生成的URL被截断,示例如下:
- 期望完整URL:
https://api.mapbox.com/geocoding/v5/mapbox.places/1000%20Innovation%20Drive%20Suite%20500.json?country=ca&fuzzyMatch=true&routing=true&proximity=-75.90307073393681%2C45.3283659706355&language=en&access_token=xxx
- 实际截断URL:
https://api.mapbox.com/geocoding/v5/mapbox.places/1285%20Teron%20Road%20
相关代码:
const functionGetDataFireBase = async () => { const dataFirebaseRes = await getDataFireBase(); const data = await getMapboxAddresses(dataFirebaseRes); console.log(data); }; functionGetDataFireBase();
export async function getMapboxAddresses(dataFromFirebase) { const mapBapboxAddressesRes = []; const tokenKey = `xxxxx`; for (const userData of dataFromFirebase) { const modifiedAddresses = userData.Addresses.replace(/ /g, "%20"); const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${modifiedAddresses}.json?country=ca&fuzzyMatch=true&routing=true&proximity=-75.90307073393681%2C45.3283659706355&language=en&access_token=${tokenKey}`; const resMap = await fetch(url); const resJSON = await resMap.json(); console.log(resJSON); } return mapBapboxAddressesRes; }
原因分析
- 原始地址含不可见控制字符:Firebase返回的部分
userData.Addresses可能存在换行符(\n)、回车符(\r)或制表符(\t),这些字符会破坏URL结构,导致请求库/浏览器自动截断URL。 - 手动编码不彻底:仅用
replace(/ /g, "%20")替换空格,既没处理其他需要URL编码的特殊字符,也未清理地址中的无效空白(比如末尾的空格或换行)。
解决方法
1. 清理无效字符+使用标准URL编码
替换手动空格编码为encodeURIComponent(标准URL编码方法),同时先清理地址中的换行、回车及多余空白:
修改getMapboxAddresses函数:
export async function getMapboxAddresses(dataFromFirebase) { const mapBapboxAddressesRes = []; const tokenKey = `xxxxx`; for (const userData of dataFromFirebase) { // 清理换行、回车、制表符,再去除首尾空白 const cleanedAddress = userData.Addresses.replace(/[\n\r\t]/g, '').trim(); // 使用标准URL编码处理地址,自动处理所有需转义的字符 const encodedAddress = encodeURIComponent(cleanedAddress); const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodedAddress}.json?country=ca&fuzzyMatch=true&routing=true&proximity=-75.90307073393681%2C45.3283659706355&language=en&access_token=${tokenKey}`; const resMap = await fetch(url); const resJSON = await resMap.json(); mapBapboxAddressesRes.push(resJSON); // 注意把结果存入返回数组 console.log(resJSON); } return mapBapboxAddressesRes; }
2. 从源头排查数据问题
登录Firebase控制台,查看截断地址对应的原始数据,确认是否存在多余的换行、空格或特殊字符,必要时在数据入库阶段就做清洗,避免后续处理出现异常。
额外优化:控制请求并发
如果dataFromFirebase数据量较大,连续的await fetch会导致请求阻塞,还可能触发Mapbox的频率限制,可通过批量并发请求优化:
// 示例:每次并发3个请求 const batchSize = 3; for (let i = 0; i < dataFromFirebase.length; i += batchSize) { const batch = dataFromFirebase.slice(i, i + batchSize); const batchPromises = batch.map(async (userData) => { const cleanedAddress = userData.Addresses.replace(/[\n\r\t]/g, '').trim(); const encodedAddress = encodeURIComponent(cleanedAddress); const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodedAddress}.json?country=ca&fuzzyMatch=true&routing=true&proximity=-75.90307073393681%2C45.3283659706355&language=en&access_token=${tokenKey}`; const resMap = await fetch(url); return resMap.json(); }); const batchResults = await Promise.all(batchPromises); mapBapboxAddressesRes.push(...batchResults); }
内容的提问来源于stack exchange,提问作者auza0002
相关产品推荐
相关产品推荐

