前言

之前曾经想自己写一个天气的App,并找到了一个免费的天气数据接口的服务商——和风天气,当时也不懂怎么发HTTP请求,而且也只会用Java语言,看到官方文档里面有一个Java代码示例,就复制了一下在自己电脑上调通。一开始是在控制台输出天气数据的,后来用Swing写了一个图形化界面并放置数据,但也就到此为止了,并没有什么实用价值。

最近学习了一下前端的相关知识,发现像和风天气这样的数据接口,根本不需要用到像Java这样的大型语言,只需在网页端用Javascript发HTTP请求就能获得JSON数据,之后再渲染到HTML网页,大大节省了资源利用和开发时间,并了解到开发这样的网页最适合的方式就是使用AJAX,因为它可以实现网页的局部更新。这样我就可以实现如下的业务场景:输入想要搜索的城市,点击搜索,下面显示出该城市的天气信息,而不影响页面的其他内容。有时候JS调用AJAX请求会有跨域问题,但和风天气的数据接口并没有这个问题。

具体场景

界面如图:

在输入框输入城市名,点击搜索按钮,可以在下面显示出各项数据(从接口获得)。

大致的HTML代码如下:

<div class="container ">
<div class="text-center">
<h1>天气查询</h1>
<div class="form-inline row">
<input type="text" class="form-control" placeholder="关键字" id="input-location"/>
<button class="btn btn-primary" onclick="loadBasic();loadAir();">搜 索</button>
</div>
</div>
<table class="table" >
<thead>
<tr>
<th>位置</th>
<th>温度</th>
<th>湿度</th>
<th>能见度</th>
<th>空气质量指数</th>
<th>更新时间</th>
</tr>
</thead>
<tbody>
<tr>
<td id="loc"></td>
<td id="tmp"></td>
<td id="hum"></td>
<td id="vis"></td>
<td id="aqi"></td>
<td id="update"></td>
</tr>
</tbody>
</table>
</div>

和风天气返回的json数据示例

{
"HeWeather6": [{
"basic": {
"cid": "CN101010100",
"location": "北京",
"parent_city": "北京",
"admin_area": "北京",
"cnty": "中国",
"lat": "39.90498734",
"lon": "116.4052887",
"tz": "+8.00"
},
"update": {
"loc": "2019-06-05 21:57",
"utc": "2019-06-05 13:57"
},
"status": "ok",
"now": {
"cloud": "91",
"cond_code": "104",
"cond_txt": "阴",
"fl": "23",
"hum": "55",
"pcpn": "0.0",
"pres": "1005",
"tmp": "23",
"vis": "16",
"wind_deg": "249",
"wind_dir": "西南风",
"wind_sc": "2",
"wind_spd": "7"
}
}]
}

下面主要描述三种我自己探索经历中使用AJAX的方法

传统AJAX

原生JS就支持AJAX,这里我借鉴了一部分网上的教程里的代码,具体的代码如下:

function loadBasic() //获取基本天气信息
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var str=xmlhttp.responseText;
var obj=JSON.parse(str);
document.getElementById("loc").innerHTML=obj.HeWeather6[0].basic.location;
document.getElementById("tmp").innerHTML=obj.HeWeather6[0].now.tmp;
document.getElementById("hum").innerHTML=obj.HeWeather6[0].now.hum+"%";
document.getElementById("vis").innerHTML=obj.HeWeather6[0].now.vis+"km";
}
}
var location=document.getElementById("input-location").value;
xmlhttp.open("GET","https://free-api.heweather.net/s6/weather/now?location="+location+"&key=我的和风天气key",true);
xmlhttp.send();
} function loadAir() //获取空气质量信息
{
//仿照上面的方法
}

原生AJAX的确能够满足业务场景的要求,但操作较为繁琐,于是我又找到了另一种方法——axios

axios

axios是对原生AJAX的封装,使用时需要导入axios.js文件包。相较于原生JS,axios使用起来更为简便,同样的功能代码如下:

function loadBasic() //获取基本天气信息
{
var location=document.getElementById("input-location").value;
axios.get('https://free-api.heweather.net/s6/weather/now?location='+location+'&key=89d49e32a26d4067822c9ed361231e2d')
.then(function (response) {
document.getElementById("loc").innerHTML=response.data.HeWeather6[0].basic.location;
document.getElementById("tmp").innerHTML=response.data.HeWeather6[0].now.tmp;
document.getElementById("hum").innerHTML=response.data.HeWeather6[0].now.hum+"%";
document.getElementById("vis").innerHTML=response.data.HeWeather6[0].now.vis+"km";
})
.catch(function (error) {
console.log(error);
});
}
function loadAir() //获取空气质量信息
{
//仿照上面的方法
}

axios是Vue.js推荐使用的实现AJAX功能的工具,Vue.js的名气我就不说了,在前端那就是如神器一般的存在。但是我们这里并没有用到Vue.js。让Vue.js和axios结合起来该怎么使用呢,请看下文

Vue.js和axios结合

一开始照着网上的教程和自己的摸索,我是这么写的(错误示范):

var vm=new Vue({
el: '#app',
data: {
inputlocation:' ',
loc:'',
tmp:'',
hum:'',
vis:'',
aqi:'',
update:'' },
methods: {
loadBasic:function(){
axios.get('https://free-api.heweather.net/s6/weather/now',{
params:{
location:this.inputlocation,
key:'89d49e32a26d4067822c9ed361231e2d'
}
})
.then(function (response) {
this.loc=(response.data.HeWeather6[0].basic.location);
this.tmp=response.data.HeWeather6[0].now.tmp;
this.hum=response.data.HeWeather6[0].now.hum+"%";
this.vis=response.data.HeWeather6[0].now.vis+"km";
})
.catch(function (error) {
console.log(error);
});
},
loadAir:function(){
axios.get('https://free-api.heweather.net/s6/air/now',{
params:{
location:this.inputlocation,
key:'89d49e32a26d4067822c9ed361231e2d'
}
})
.then(function (response) {
this.update=response.data.HeWeather6[0].update.loc;
this.aqi=response.data.HeWeather6[0].air_now_city.aqi;
})
.catch(function (error) {
console.log(error);
});
} }
})

同时HTML也有较大的改动,我在此列出:

<div class="container " id="app">
<div class="text-center">
<h1>天气查询</h1>
<div class="form-inline row">
<input type="text" class="form-control" placeholder="关键字" id="input-location" v-model="inputlocation"/>
<button class="btn btn-primary" @click="loadBasic();loadAir()">搜 索</button>
</div>
</div>
<table class="table" >
<thead>
<tr>
<th>位置</th>
<th>温度</th>
<th>湿度</th>
<th>能见度</th>
<th>空气质量指数</th>
<th>更新时间</th>
</tr>
</thead>
<tbody>
<tr>
<td id="loc">{{loc}}</td>
<td id="tmp">{{tmp}}</td>
<td id="hum">{{hum}}</td>
<td id="vis">{{vis}}</td>
<td id="aqi">{{aqi}}</td>
<td id="update">{{update}}</td>
</tr>
</tbody>
</table>
</div>

但是发现不能成功实现,而且确认数据应该是绑定上了,甚至在控制台手动执行axios方法(将this改成vm)都能成功。后来经过一番搜索,再加上室友的神助攻,发现原来axios方法里面的this已经不是指向vm对象了,因为已经经过了两层方法。这种情况在非严格模式下this会被当做window,在严格模式下this不可用。解决这个问题的方法有两种

  1. 在第一层方法内指定that=this,在第二层方法内把this替换成that
  2. 使用ES6的箭头函数

第一种方法的代码如下:

loadBasic:function(){
let that = this; //如果在response方法里用this,会错误
axios.get('https://free-api.heweather.net/s6/weather/now',{
params:{
location:this.inputlocation,
key:'89d49e32a26d4067822c9ed361231e2d'
}
})
.then(function (response) {
that.loc=(response.data.HeWeather6[0].basic.location);
that.tmp=response.data.HeWeather6[0].now.tmp;
that.hum=response.data.HeWeather6[0].now.hum+"%";
that.vis=response.data.HeWeather6[0].now.vis+"km";
})
.catch(function (error) {
console.log(error);
});
},
loadAir:function(){
let that = this; //如果在response方法里用this,会错误
axios.get('https://free-api.heweather.net/s6/air/now',{
params:{
location:this.inputlocation,
key:'89d49e32a26d4067822c9ed361231e2d'
}
})
.then(function (response) {
that.update=response.data.HeWeather6[0].update.loc;
that.aqi=response.data.HeWeather6[0].air_now_city.aqi;
})
.catch(function (error) {
console.log(error);
});
}

第二种方法的代码如下

loadBasic:function(){
axios.get('https://free-api.heweather.net/s6/weather/now',{
params:{
location:this.inputlocation,
key:'89d49e32a26d4067822c9ed361231e2d'
}
})
.then((response)=> {
this.loc=(response.data.HeWeather6[0].basic.location);
this.tmp=response.data.HeWeather6[0].now.tmp;
this.hum=response.data.HeWeather6[0].now.hum+"%";
this.vis=response.data.HeWeather6[0].now.vis+"km";
})
.catch(function (error) {
console.log(error);
});
},
loadAir:function(){
axios.get('https://free-api.heweather.net/s6/air/now',{
params:{
location:this.inputlocation,
key:'89d49e32a26d4067822c9ed361231e2d'
}
})
.then((response)=> {
this.update=response.data.HeWeather6[0].update.loc;
this.aqi=response.data.HeWeather6[0].air_now_city.aqi;
})
.catch(function(error) {
console.log(error);
});
}

最后成功用现在新潮的技术实现了我的网页,还是挺美滋滋的。

三种实现AJAX的方法以及Vue和axios结合使用的坑的更多相关文章

  1. 三种实现Ajax的方式

    本文主要是比较三种实现Ajax的方式 1. prototype.js 2. jquery1.3.2.min.js 3. json2.js Java代码 收藏代码 后台处理程序(Servlet),访问路 ...

  2. iOS 三种收起键盘的方法

    - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...

  3. 【读书笔记】iOS-开发技巧-三种收起键盘的方法

    - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...

  4. File类三种得到路径的方法

    转: File类三种得到路径的方法 2010年11月29日 20:37:00 ssyan 阅读数:27123 标签: filemicrosoftstringexceptionwindowsunix   ...

  5. 【转】python 三种遍历list的方法

    [转]python 三种遍历list的方法 #!/usr/bin/env python # -*- coding: utf-8 -*- if __name__ == '__main__': list ...

  6. 【Java 线程的深入研究1】Java 提供了三种创建线程的方法

    Java 提供了三种创建线程的方法: 通过实现 Runnable 接口: 通过继承 Thread 类本身: 通过 Callable 和 Future 创建线程. 1.通过实现 Runnable 接口来 ...

  7. Oracle数据库三种标准的备份方法

    Oracle数据库的三种标准的备份方法: 1.导出/导入(EXP/IMP). 2.热备份. 3.冷备份. 注释:导出备件是一种逻辑备份,冷备份和热备份是物理备份. 一.导出/导入(Export/Imp ...

  8. iOS用三种途径实现一方法有多个返回值

    以前觉得这种标题有点偏向于理论,实际开发中怎么会有这种诡异的需求,但是真正遇到了这种硬需求时觉得还是有那么点价值的,理论付诸了实践在此也就做了个整理. 以我私下开发中的一处代码为例,本意是希望有这么一 ...

  9. Java Web开发Tomcat中三种部署项目的方法

    第一种方法:在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加: <Context path="/hello" docBase ...

随机推荐

  1. uva 10604

    状态压缩  奇怪的是A与B混合 和 B与A 混合得到的热量可能不同 #include <cstdio> #include <cstdlib> #include <cmat ...

  2. [Poj2096]Collecting Bugs(入门期望dp)

    Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 6237   Accepted: 3065 ...

  3. ExtJS学习-----------Ext.Object,ExtJS对javascript中的Object的扩展

    关于ExtJS对javascript中的Object的扩展.能够參考其帮助文档,文档下载地址:http://download.csdn.net/detail/z1137730824/7748893 以 ...

  4. 基于FFMPEG SDK流媒体开发1---解码媒体文件流信息

    近期项目涉及到流媒体等开发,因为有过开发经验深知其难度所在,没办法仅仅能又一次拾起,最新版的SDK被改的一塌糊涂,只是大体的开发思路都是一样的,看多少书查多少资料都无用,一步一步的编写代码 才是学好的 ...

  5. Vi/Vim查找替换使用方法【转】

    原文地址:http://wzgyantai.blogbus.com/logs/28117977.html vi/vim 中可以使用 :s 命令来替换字符串.该命令有很多种不同细节使用方法,可以实现复杂 ...

  6. 最简单的基于FFmpeg的移动端样例:IOS 视频转码器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  7. SVN下Update出现代码文件删除状态问题

    有时候在SVN上更新了代码,发觉别人提交的东西,服务上明明就是有,但本机却空空如也.只好打开 "Repo-browser",从服务器上强拉下来.结果图标显示红叉,显示为删除状态. ...

  8. mysql数据库存放路径

    在你的my.ini 文件中定义的参数 datadir 指定的目录中. SQL code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> select @@da ...

  9. ubuntu安装jdk 1.6

    linux下安装JDK1.6 1. 去http://java.sun.com/j2se/1.4.2/download.html 下载一个Linux Platform的JDK,建议下载RPM自解压格式的 ...

  10. ECharts 使用

    最近项目中要做图形报表,要求使用echarts实现,图形报表有很多中实现之前也接触过,但echarts还是头一次听说,正好可以趁这个机会好好学习一下它. 之前不知道就不知道啦,现在知道了就了不得了,一 ...