Javascript 边栏小工具中XHR的未定义响应文本
我正试图从api.openweathermap.org编写一个显示当前温度的小工具。 该小工具通过setTimeout循环中的异步XMLHttpRequest获取信息,因此天气数据每隔几分钟更新一次,但有时XHR的responseText未定义,这当然会引发错误并停止循环,并且不可避免地停止更新过程 Fiddler显示流量消失,响应返回有效的预期数据,但XHR无法以某种方式访问它 相关的JS位:Javascript 边栏小工具中XHR的未定义响应文本,javascript,xmlhttprequest,windows-desktop-gadgets,Javascript,Xmlhttprequest,Windows Desktop Gadgets,我正试图从api.openweathermap.org编写一个显示当前温度的小工具。 该小工具通过setTimeout循环中的异步XMLHttpRequest获取信息,因此天气数据每隔几分钟更新一次,但有时XHR的responseText未定义,这当然会引发错误并停止循环,并且不可避免地停止更新过程 Fiddler显示流量消失,响应返回有效的预期数据,但XHR无法以某种方式访问它 相关的JS位: var timer; // these three var locStr; //
var timer; // these three
var locStr; // are defined
var weather; // elsewhere
function showWeather()
{
System.Debug.outputString('showWeather()');
if (timer) clearTimeout(timer);
locStr = System.Gadget.Settings.readString("location");
// this is for first-run use only - when the setting is not set, display an appropriate notification to the user
if (locStr == "")
{
cell.style.display = 'none';
welcome.style.display = 'block';
}
else
{
cell.style.display = 'block';
welcome.style.display = 'none';
updateWeather();
}
}
function updateWeather()
{
System.Debug.outputString('updateWeather()');
try
{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
System.Debug.outputString('updateWeather()>onreadystatechange ' + xhr.status + ' ' + xhr.readyState);
if (xhr.status === 200)
{
if (xhr.readyState === 4)
{
// this is what makes it fail:
System.Debug.outputString(xhr.responseText);
weather = eval('(' + xhr.responseText + ')'); // i DO get that eval is evil, but works for my purposes well.
// temp, city, wind and clouds are html entities id values
temp.innerHTML = Math.round(weather.main.temp) + '<span>°C</span>';
city.innerHTML = weather.name;
wind.innerHTML = weather.wind.speed + ' m/s';
clouds.innerHTML = weather.clouds.all + '%';
// clears and hides error, if occured in previous fetch
error_title.innerHTML = '';
error_description.innerHTML = '';
error.style.display = 'none';
timer = setTimeout(updateWeather, 1000 * 5);
}
else
{
temp.innerText += '.';
}
}
else
{
error_title.innerText = 'Connectivity error';
error_description.innerText = xhr.status + '.'; // that's really informative...
error.style.display = 'block';
timer = setTimeout(updateWeather, 5000)
}
};
xhr.ontimeout = function()
{
error_title.innerText = 'Connectivity error';
error_description.innerText = 'timed out';
error.style.display = 'block';
timer = setTimeout(updateWeather, 5000);
};
xhr.open('get', 'http://api.openweathermap.org/data/2.5/weather?q=' + locStr + '&units=metric&dummy=' + Math.ceil(100*Math.random()), false);
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.send();
}
catch (e)
{
error_title.innerText = e.name;
error_description.innerText = e.message;
error.style.display = 'block';
timer = setTimeout(updateWeather, 5000);
}
}
然而,在我的小工具中,检索数据没有问题
这很可能是由于浏览器中实现的跨域安全策略跨源资源共享—CORS、W3C机制。通过javascript对来自不同域的资源的HTTP请求将失败。如果服务器支持,您可以使用JSONP解决此问题。要启用CORS,您尝试连接到的服务器需要将您的域添加到Access Control Allow Origin HTTP头中,或允许使用星号通配符“*”指示的所有域 MDN供参考的文章-
有人已经记录了此问题:我相信在小工具环境中不会强制执行同源策略。为了支持我的说法,这个小工具首先工作,对于前三次左右的UpdateWather调用,responseText字段是可访问的。但事实并非如此,这让我挠头。嗯,好吧,听起来与浏览器中CORS出现的问题完全相同,没有错误,在检查网络流量时响应是正确的,但javascript无法访问它。我不熟悉构建windows小工具,但我认为它们运行在某种无铬浏览器中?我想在Fiddler中检查标题信息可能会有所帮助。
XMLHttpRequest cannot load http://weather.yahooapis.com/forecastrss?w=526363&u=c.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://fiddle.jshell.net' is therefore not allowed access.