Javascript 如何在CodePen中从外部提供者获取数据?

Javascript 如何在CodePen中从外部提供者获取数据?,javascript,cors,Javascript,Cors,我正在进行JavaScript挑战。其中之一是创建一个检索和显示天气信息的网页 首先,我尝试使用几个提供者(例如OpenWeatherMap),它们使用HTTP协议返回天气数据。因为这个错误,它不起作用 接下来,我切换到一个提供者,它通过HTTPS提供数据。我解决了混合内容的问题,但还有一个问题: 无法加载XMLHttpRequest。请求的资源上不存在“Access Control Allow Origin”标头。因此,不允许访问源“”。响应的HTTP状态代码为403 我尝试根据以下内容实施C

我正在进行JavaScript挑战。其中之一是创建一个检索和显示天气信息的网页

首先,我尝试使用几个提供者(例如OpenWeatherMap),它们使用HTTP协议返回天气数据。因为这个错误,它不起作用

接下来,我切换到一个提供者,它通过HTTPS提供数据。我解决了混合内容的问题,但还有一个问题:

无法加载XMLHttpRequest。请求的资源上不存在“Access Control Allow Origin”标头。因此,不允许访问源“”。响应的HTTP状态代码为403

我尝试根据以下内容实施CORS:

当我调用
xhr.send()
时,仍然会出现错误

我怎样才能修好它

注意:我正在寻找一个将在中运行的解决方案

更新1(23.03.2017 11:35 MSK):我试图实现sideshowbarker的答案,并修改了如下代码:

function getCurrent(json){
     console.log("getCurrent called");
     console.log(json.data.temp);
     console.log(json.data.precip);
}

function updateWeather() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      var url = "https://api.weatherbit.io/v1.0/current?callback=getCurrent&lat=" + position.coords.latitude + "&lon=" + position.coords.longitude + "&units=S&key=XXXXXXXXX";
      console.log("url: " + url);
      $.get(url, function(val){});
    });
  } else {
    console.log("Cannot obtain location data");
  };
}

updateWeather();
结果是:

更新2(23.03.2017 13:29 MSK):这一个有效

 function getCurrent(json) {
   console.log("getCurrent called");
   console.log(JSON.stringify(json));
   // TODO: Update the UI here
 }

 function updateWeather() {
   if (navigator.geolocation) {
     navigator.geolocation.getCurrentPosition(function(position) {
       var url = "https://api.darksky.net/forecast/XXXXXXXXX/37.8267,-122.4233?callback=getCurrent";

       var script = document.createElement('script');
       script.src = url;

       document.getElementsByTagName('head')[0].appendChild(script);

     });
   }
 }

 updateWeather();

Weatherbit.io API不支持从XHR发出的跨源请求

相反,API要求您使用带有JSONP回调的
脚本
元素发出请求:

<script>
    function getCurrent(json){
        console.log(json.data.temp)
        console.log(json.data.precip)
    }
</script>

<script
src="https://api.weatherbit.io/v1.0/current?callback=getCurrent&lat=NNN&lon=NNN&units=S&key=XX"></script>

函数getCurrent(json){
log(json.data.temp)
log(json.data.precip)
}
当然,您可能希望让代码使用URL和参数注入
script
元素

这就是用JSONP回调注入
script
元素的方法,这是他们支持的从web应用程序使用API的唯一直接方法

如果代码使用XHR向其API发出请求,那么代码将无法工作;它们不发送必要的
Access Control Allow Origin
response标头,因此,由于缺少该标头,浏览器将不允许客户端JavaScript跨源访问响应

解释了原因

使用XHR处理其API的唯一方法是,如果您使用源代码或类似代码设置CORS代理,或者通过公共CORS代理发送请求,例如(您不想这样做,因为这样会使该服务的所有者能够访问您的Weatherbit.io API密钥)


代理的工作方式是使用代理URL,而不是使用weatherbit.io URL,如
https://cors-anywhere.herokuapp.com/https://api.weatherbit.io/v1.0/current…
,代理将其发送到weatherbit.io,并返回响应,然后将
访问控制允许来源
响应头添加到返回给您的代码并由浏览器看到的响应。

我当时正在FCC中完成天气应用程序,遇到了相同的问题。我能够通过以下线路使其工作:

$.getJSON("https://api.weatherbit.io/v1.0/current?lat=##&lon=##&key=##", function(data){};
不管出于什么原因,它不能只使用“http://”,我必须将它改为“https://”,才能工作


不确定这是否有助于将来的任何人。

您的更新没有使用我提出的解决方案。相反,它使用jQuery$.get(…),这在功能上与仅使用本机XHR相同。如果您想使用jQuery进行此操作,请考虑使用$.GETJSON(),它将做一些幕后魔术来正确处理JSONP请求响应,而不使用XHR。在没有jQuery的情况下如何调用URL?如果没有jQuery,您需要在代码中创建一个
script
元素,以与现在相同的方式构建URL,将
src
属性添加到带有该URL的
script
元素,然后将该
script
元素附加到文档中。有关这方面的指导,请参见和
$.getJSON("https://api.weatherbit.io/v1.0/current?lat=##&lon=##&key=##", function(data){};