【问题标题】:Fetch response and parse to json getting html instead of the JSON data at the URL获取响应并解析为 json 获取 html 而不是 URL 处的 JSON 数据
【发布时间】:2021-10-26 21:15:34
【问题描述】:

我显然在这里得到了 HTML,但我不明白为什么。这是预期获取数据并将 URL 解析为 json 的函数,但即使控制台在使用 console.log(res) 时显示 URL,当我尝试 res.json() 时,我也会得到 rejected promise

const fetchData = async () => {
      navigator.geolocation.getCurrentPosition(function(position) {
        setLat(position.coords.latitude);
        setLong(position.coords.longitude);
      });

      await fetch(`${process.env.REACT_APP_API_URL}/weather?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`)
      .then(res => console.log(res)) //expected URL appears in the console. 
      
    }
    fetchData();
  }, [lat,long])

尝试 res.text() 来查看正在获取的响应并>得出结论,我正在从公共目录中获取 HTML 文件。 (考虑到意外的标记,我假设它是 HTML。)我不明白 >为什么它不解析为 JSON,而是获取 HTML。 console HTML info我在控制台中看到了这个,但不知道从这里做什么

我还在应用程序的控制台中检查了 fetch('https://api.openweathermap.org/data/2.5/weather?lat=28.052684799999998&lon=-82.427904&APPID=d8c1409b5342d12f52e6dce35fc26aac') 并返回了一个未决的承诺。 console results

我上传了repo以便更好地理解 是否因为环境变量而发生一些混乱?

【问题讨论】:

  • 返回的数据不是 JSON。它不是 JSON。
  • navigator.geolocation.getCurrentPosition(function(position) { setLat(position.coords.latitude); setLong(position.coords.longitude); }); 是异步的......你的 lat 和 lng 不会被设置
  • 在控制台写fetch(url).then(response => response.text()).then(console.log)查看响应。它说响应以< 开头,因此它很可能是 XML 或 HTML,而不是 JSON。一种可能的解释是 API 默认提供 XML,而您忘记添加 Accept: application/json 标头。不过,console.logging 响应应该会告诉你出了什么问题。

标签: javascript reactjs environment-variables fetch-api


【解决方案1】:

由于我对您要获取的网址一无所知,我只能猜测您的网址格式和后端reject您有错误。即使服务器在正常情况下发送json数据,如果你的url有错误,它也会发送诸如服务器错误、404错误之类的错误页面。

复制网址并将其粘贴到新的浏览器选项卡中并检查响应。我认为您可能会收到错误页面。

【讨论】:

  • 我已经复制并粘贴了几次 URL,我得到了我期望的 json。这就是为什么我很困惑。感谢您的帮助
【解决方案2】:

因为你获取的文档是 HTML 格式而不是 JSON 格式

HTML

<!DOCTYPE html> 开头(括号){抛出错误}

JSON

format : {"latitude":"-0289201019", "longitude":"-0289201019"}

使用res.text()进行调试

【讨论】:

  • @JelenaFeliciano 你读过 HTML 的内容吗?它可能包含有用的信息。
【解决方案3】:

嗯,这似乎有点复杂,因为我无法像你一样得到结果。但我认为有办法。

正如你提到的,它返回的是 HTML 格式,首先使用 this 将其转换为 html。

var html = new DOMParser().parseFromString(data, "text/xml") 

html.documentElement 会像这样返回HTML

<html>
    <head></head>
    <body></body>

使用 console.log 查看结果。如果 json 字符串在 body 中,您可以使用普通的 javascript 函数来获取结果。

例如,您可以使用以下方法获取body 内容

html.documentElement.getElementsByTagName('body')[0].textContent

【讨论】:

    【解决方案4】:

    我不确定这是一个解决方案,但your current code 存在一些问题。

    //create two states for longitude and latitude
    const [lat, setLat] = useState([]);
    const [long, setLong] = useState([]);
    //const [data, setData] = useState([]);
    
    useEffect(() => {
      const fetchData = async () => {
        navigator.geolocation.getCurrentPosition(function(position) {
          setLat(position.coords.latitude);
          setLong(position.coords.longitude);
        });
    
        await fetch(`${process.env.REACT_APP_API_URL}/weather?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`)
        .then(res => console.log(res))
      
      }
      fetchData();
    }, [lat,long])
    
    1. 为什么使用空数组作为latlong 的默认状态?纬度和经度是数字。要么将它们表示为0,要么使用null 表示该值尚未加载。

      const [lat, setLat] = useState(null);
      const [lon, setLon] = useState(null);
      

      我将使用null 来表示一个未加载的值。

    2. useEffect(callback, [lat, lon]) 将在latlon 或两者都发生变化时触发。然后您将调用getCurrentPosition() 并覆盖更改的值。这不是一个合乎逻辑的事情。加载当前位置是一个很好的起始位置,但每当用户更改latlon 我假设您想要获取所提供位置的天气。

      每次lat/lon 更改时,您当前都使用当前位置覆盖lat/lon。最好的办法是拆分操作:

      // load the current location only on component mount as starting point
      useEffect(() => {
        navigator.geolocation.getCurrentPosition(function(position) {
          setLat(position.coords.latitude);
          setLon(position.coords.longitude);
        });
      }, []); // <- empty dependency list
      
      // retrieve new weather info each time lat or lon changes
      useEffect(() => {
        // Make sure both lat and lon are present before firing a fetch request.
        // Can't use truthy/falsy because 0 is a valid coordinate, but is falsy.
        if (lat == null) return;
        if (lon == null) return;
      
        fetch(`.../weather?lat=${lat}&lon=${lon}&...`)
          .then(res => res.json())
          .then(data => console.log(data));
      }, [lat, lon]); // <- having lat/lon as dependencies
      

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    相关资源
    最近更新 更多