Firefox扩展调用MapQuest API出现TypeError: NetworkError问题求助
问题:Firefox扩展调用MapQuest API出现NetworkError
我正在开发一款Firefox扩展,尝试通过MapQuest API获取数据。起初API运行正常,但突然开始报错:TypeError: NetworkError when attempting to fetch resource。以下是我的manifest配置和脚本代码:
manifest配置
{ "manifest_version": 3, "name": "Distance", "version": "1.0", "description": "distance between cities", "permissions": ["storage", "activeTab"], "content_scripts": [ { "matches": ["http://*/Prise_en_charge_OM.aspx"], "js": ["script.js"] } ] }
脚本代码
if (window.location.href.includes("/Prise_en_charge_OM.aspx")) { var apiKey = "<API-KEY>"; const tableElement = document.getElementById( "ContentPlaceHolder1_ContentPlaceHolder2_grv_villes" ); // Load table data from localStorage if available const storedTable = retrieveTable(); if (storedTable) { console.log("Table data retrieved from localStorage."); tableElement.outerHTML = storedTable; } const el_form = document.getElementById("form1"); el_form.addEventListener("submit", function (e) { if ( e.submitter.id === "ContentPlaceHolder1_ContentPlaceHolder2_btn_ajouterjours" ) { const data = retrieveFromTable(tableElement); updateTableWithDistance(tableElement, data); storeTable(tableElement.outerHTML); } }); } function storeTable(tbl) { localStorage.setItem("tbl", tbl); } function retrieveTable() { return localStorage.getItem("tbl"); } async function retrieveFromTable(table) { const storedData = retrieveDistance() || []; const from = table.rows[1].cells[1].textContent; const data = []; for (let row = 2; row < table.rows.length; row++) { const to = table.rows[row].cells[1].textContent; const existingDist = storedData.find( (dist) => dist.from === from && dist.to === to ); if (existingDist) { data.push(existingDist); } else { const resp = await calculateDrivingDistances(from, to); console.log(resp); const newDist = { from, to, distance: resp }; data.push(newDist); storedData.push(newDist); storeDistance(storedData); } } console.log(data); return data; } function updateTableWithDistance(table, data) { if (table.rows.length > 0) { const headerRow = table.rows[0]; const newHeaderCell = document.createElement("th"); newHeaderCell.textContent = "Distance"; headerRow.appendChild(newHeaderCell); for (let row = 1; row < table.rows.length; row++) { const dataRow = table.rows[row]; const to = dataRow.cells[1].textContent; console.log(data); //let distObj = data.find((dist) => dist.to === to); let distObj; data.then((resp) => { distObj = resp.find((dist) => dist.to === to); console.log(distObj); if (distObj) { const newDataCell = document.createElement("td"); newDataCell.textContent = distObj.distance; dataRow.appendChild(newDataCell); } }); } } } function storeDistance(data) { localStorage.setItem("distances", JSON.stringify(data)); } function retrieveDistance() { const val = localStorage.getItem("distances"); return val ? JSON.parse(val) : []; } async function calculateDrivingDistances(city1, city2) { const url = `https://www.mapquestapi.com/directions/v2/route?key=${apiKey}&from=${encodeURIComponent( city1 )}&to=${encodeURIComponent(city2)}&unit=k`; try { const response = await fetch(url); console.log("status: ", response.status); if (!response.ok) { throw new Error( `Network response was not ok, status: ${response.status}` ); } const data = await response.json(); if (data.route && data.route.distance) { const distanceKm = data.route.distance; return distanceKm; } else { console.log("API Error: No distance data in response"); return 0; } } catch (error) { console.error("Error in calculateDrivingDistances:", error); return 0; } }
排查与解决指导
补全跨域权限声明
Manifest V3中,内容脚本访问外部API必须明确声明host_permissions。在你的manifest.json中添加以下配置:"host_permissions": ["https://www.mapquestapi.com/*"]这是解决跨域NetworkError最直接的方案,因为内容脚本受同源策略限制,未声明的外部域名会被浏览器拦截。
验证API密钥有效性
直接在浏览器地址栏拼接完整请求URL(替换<API-KEY>为真实密钥,城市名用测试值),比如:https://www.mapquestapi.com/directions/v2/route?key=你的真实密钥&from=Paris&to=Lyon&unit=k如果返回错误,检查MapQuest开发者后台的密钥状态:是否过期、调用额度是否用尽、密钥是否输入错误。
修正异步逻辑漏洞
retrieveFromTable是异步函数,返回的是Promise,但你在submit事件中直接将其传给updateTableWithDistance,后续处理容易出问题。修改事件监听逻辑:el_form.addEventListener("submit", async function (e) { if (e.submitter.id === "ContentPlaceHolder1_ContentPlaceHolder2_btn_ajouterjours") { e.preventDefault(); // 阻止页面刷新,避免重复请求 const data = await retrieveFromTable(tableElement); updateTableWithDistance(tableElement, data); storeTable(tableElement.outerHTML); } });同时简化
updateTableWithDistance,不需要再处理Promise:function updateTableWithDistance(table, data) { if (table.rows.length === 0) return; // 避免重复添加表头 const hasDistanceHeader = Array.from(table.rows[0].cells).some(cell => cell.textContent === "Distance"); if (!hasDistanceHeader) { const newHeaderCell = document.createElement("th"); newHeaderCell.textContent = "Distance"; table.rows[0].appendChild(newHeaderCell); } // 从第2行开始处理(第1行是出发城市) for (let row = 2; row < table.rows.length; row++) { const dataRow = table.rows[row]; const to = dataRow.cells[1].textContent; const distObj = data.find(dist => dist.to === to); // 避免重复添加单元格 if (distObj && dataRow.cells.length <= 2) { const newDataCell = document.createElement("td"); newDataCell.textContent = distObj.distance; dataRow.appendChild(newDataCell); } } }查看浏览器网络日志
打开Firefox开发者工具(F12)→「网络」标签,触发API请求后查看:- 请求状态码:401代表密钥无效,403代表额度用尽,404代表URL错误
- 响应详情:MapQuest会返回具体错误信息,帮助定位问题
内容的提问来源于stack exchange,提问作者tawfiq
相关产品推荐
相关产品推荐

