今天在做一个页面,可以显示时钟以及天气。天气数据用到了一个接口,利用ajax去访问这个接口的时候,遇到了一些问题。在这里记录下问题的解决方法。
由于接口和客户端不在同一个域下,所以要进行跨域访问,而ajax不能跨域访问,只能用jsonp方法去跨域。但是一旦跨域后,ajax的设置就对jsonp无效了,比如async:fakse就失效了。
也就是说,我想使用的接口返回回来的数据在使用的时候拿不到,因为是异步的,所以当走到使用数据的地方时,数据还没从接口那里获得到。
解决方法是:
延迟执行使用数据的操作。以确保想要的数据已经拿到并赋好值了。
具体代码如下:
//作者:耍流氓的兔兔
var mainpage = new Vue({
el: "#mainpage",
data: {
min: "",
time: "",
date: "",
city: "",
weather: "",
temperature: "",
aphorism: "",
},
watch: {
min: function(val, obdvalue) {
updatetext();
},
deep: true
}
});
updateTime();
updatetext();
//添加定时器
var timerID = setInterval("updateTime()", 200);
var date_c;
var w;
var t;
function updateTime() {
//Date对象用于处理日期和时间
//Date对象会自动把当前日期和时间保存为其初始值
var cd = new Date();
var week = ["星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
mainpage.min = zeroPadding(cd.getMinutes(), 2);
mainpage.time = zeroPadding(cd.getHours(), 2) + ":" + mainpage.min + ":" + zeroPadding(cd.getSeconds(), 2);
//getFullYear():以四位数返回年份
//getMonth():返回月份(0~11)
//getDay():返回一周中的某一天
//getDate():返回一个月中的某一天
mainpage.date = zeroPadding(cd.getFullYear(), 4) + "-" + zeroPadding(cd.getMonth() + 1, 2) + "-" + zeroPadding(cd.getDate(), 2) + " " + week[cd.getDay()];
};
//格式化日期时间
function zeroPadding(num, digit) {
var zero = "";
for(var i = 0; i < digit; i++) {
zero += "0";
}
//slice(start, end):从已有的数组中返回选定的元素
//start如果为负,规定从数组尾部开始算起的位置
return(zero + num).slice(-digit);
}
function updatetext() {
//生成随机数
var index = Math.floor(Math.random() * aphorismdata.length);
mainpage.aphorism = aphorismdata[index];
}
/*
* 确定所在城市
*/
function findcity() {
//调用新浪的根据ip查城市的接口
var cityUrl = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js";
$.getScript(cityUrl, function() {
// var country=remote_ip_info.country;
// var province=remote_ip_info.province;
var city = remote_ip_info.city;
mainpage.city = city;
show(mainpage.city);
})
}
/*
* 获取当地城市的天气情况
*/
function findweather(city) {
//为避免广告嫌疑
var url = "你要连接的接口url";
$.ajax({
url: url,
type: "get",
// async: false,
dataType: "jsonp",
success: function(data) {
var today = data.result.today;
mainpage.weather = today.weather;
mainpage.temperature = today.temperature;
}
});
}
/*
* 修改人:Lucifer
* 修改时间:2017年8月26日 21:05
* 修改说明:
* 由于接口访问次数有限,而且天气每天基本不会变化,所以没必要每次刷新或者连接都要去访问接口取值
* 基于这,可以使用cookie来存储天气、温度。从而减少对接口的访问
*/
function setCookie(c_name, value, days) {
var exdate = new Date();
exdate.setDate(exdate.getDate() + days);
document.cookie = c_name + "=" + escape(value) + ";" + ((days == null) ? "" : "expires=" + exdate.toGMTString());
}
function getCookie(c_name) {
if(document.cookie.length > 0) {
var c_start = document.cookie.indexOf(c_name + "=");
var c_end = -1;
if(c_start != -1) {
c_start = c_start + c_name.length + 1;
c_end = document.cookie.indexOf(";", c_start);
if(c_end == -1) {
c_end = document.cookie.length;
}
return unescape(document.cookie.substring(c_start, c_end));
}
}
}
function show(city) {
var date_n = new Date();
date_n = zeroPadding(date_n.getFullYear(), 4) + "-" + zeroPadding(date_n.getMonth() + 1, 2) + "-" + zeroPadding(date_n.getDate(), 2);
if(getCookie("city") == undefined || getCookie("city") != city || getCookie("updatetime" ) != date_n) {
findweather(city);
/*
* 通过延迟执行使得ajax跨域后可以获得ajax的返回值,不然,ajax跨域后同步设置会失效,无法获得返回数据
* 此bug耗时4小时
*/
setTimeout(function() {
setCookie("city", city, 1);
setCookie("weather", mainpage.weather, 1);
setCookie("temperature", mainpage.temperature, 1);
setCookie("updatetime", date_n, 1);
}, 1000);
} else {
mainpage.weather = getCookie("weather");
mainpage.temperature = getCookie("temperature");
}
}
findcity();
算是一种解决方法,网上还有利用回调函数的,由于我是初学者,还没搞明白回调函数,这里就不写了。真是,昨晚调了两小时,由于不了解ajax,瞎折腾,居然没意识到是由于ajax的跨域访问出了问题。
总算是解决了。
效果图:
以上。
2017/8/27
Lucifer