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