You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:45:02