AJAX(七)jsonp实战--天气预报
一、案例
本次要做的案例的是使用jsonp制作一个查询天气情况的网页,我会从如何抓取数据接口,到一步一步完成这个案例来详细讲解。
这个页面样式非常简单,截图如下。用户需要先选择一个城市,然后点击查看天气,那么最近5天的天气数据,就会展示到下面。
二、数据从何而来
当然我们不可能自己建气象站,我们只有通过互联网拿到别人“分享”给我们的数据接口,然后通过这个数据接口获取全国的气象数据。这样我们就必须使用jsonp了,因为提供气象数据服务的api,其所在的域名肯定跟我们自己的应用程序不是一个域名。
那么问题来了,我们如何知道哪里有api提供气象数据服务的?这个就要多观察多积累了。比如现在很多人的电脑上都会安装360,一般360杀毒在安装时候会篡改你的浏览器主页为“hao360”这个网站,那么你打开网页,每次都会看到这样的画面。
这个网站在非常显眼的地方提供了一个查看天气的模块。难道360还开着气象站?如果不是,那我们只要看看它是如何搞到数据的,我们就能如法炮制了。
一般你可以这样做:
1.在气象模块上点鼠标右键->审查元素。去看看他的结构
2.打开开发者选项工具窗口,点击Network(网络)选项卡,然后去查看请求报文,这样就能找到气象数据从哪儿来了。
不过,如果你没有经验,你会被请求报文列表中的数据给吓住,因为实在是太多了,至少不下300条请求项。那我们怎么去找真正需要的那个请求呢?
试想,这个hao360也不可能自己弄个气象站,所以它必然也是抓取的第三方api,所以也必然是通过jsonp的形式来实现的。那么我们只需要在所有的请求报文中按type这一列排下序,然后就只管看请求类型是script的那些项。这样一下就把范围缩小了很多很多。
最后我们找到,这里的请求url是:https://cdn.weather.hao.360.cn/sed_api_weather_info.php?code=101180201&app=hao360&_jsonp=__jsonp3__
简单说明下这个url的参数
1.code:要查询的城市编码,这个可以百度
2._jsonp:你自己定义的回调函数的名字。
3.其他的参数都无关紧要,至少对本案例来说是这样。
在浏览器里打开这个链接,你看到的结果是这样的:
当然,我只截取了一小部分。不过已经可以看出了,这是一个典型的jsonp跨域访问。
然后,我把数据copy出来,贴到sublime中,格式化之后,数据是这个样子的。
1 { 2 "pubdate": "2018-06-25", 3 "pubtime": "16:44:10", 4 "time": 1529916250, 5 "area": [ 6 ["\u6cb3\u5357", "18"], 7 ["\u5b89\u9633", "1802"], 8 ["\u5b89\u9633", "101180201"] 9 ], 10 "weather": [{ 11 "date": "2018-06-25", 12 "info": { 13 "dawn": ["2", "\u9634", "24", "\u5357\u98ce", "\u5fae\u98ce", "19:44"], 14 "day": ["8", "\u4e2d\u96e8", "27", "\u5317\u98ce", "\u5fae\u98ce", "05:07"], 15 "night": ["8", "\u4e2d\u96e8", "22", "\u897f\u98ce", "\u5fae\u98ce", "19:44"] 16 } 17 }, { 18 "date": "2018-06-26", 19 "info": { 20 "dawn": ["8", "\u4e2d\u96e8", "22", "\u897f\u98ce", "\u5fae\u98ce", "19:44"], 21 "day": ["7", "\u5c0f\u96e8", "28", "\u5357\u98ce", "\u5fae\u98ce", "05:07"], 22 "night": ["1", "\u591a\u4e91", "22", "\u5357\u98ce", "\u5fae\u98ce", "19:44"] 23 } 24 }, { 25 "date": "2018-06-27", 26 "info": { 27 "dawn": ["1", "\u591a\u4e91", "22", "\u5357\u98ce", "\u5fae\u98ce", "19:44"], 28 "day": ["0", "\u6674", "37", "\u5357\u98ce", "\u5fae\u98ce", "05:08"], 29 "night": ["0", "\u6674", "24", "\u5317\u98ce", "3-5\u7ea7", "19:44"] 30 } 31 }, { 32 "date": "2018-06-28", 33 "info": { 34 "dawn": ["0", "\u6674", "24", "\u5317\u98ce", "3-5\u7ea7", "19:44"], 35 "day": ["0", "\u6674", "36", "\u4e1c\u5317\u98ce", "\u5fae\u98ce", "05:08"], 36 "night": ["1", "\u591a\u4e91", "21", "\u897f\u98ce", "\u5fae\u98ce", "19:45"] 37 } 38 }, { 39 "date": "2018-06-29", 40 "info": { 41 "dawn": ["1", "\u591a\u4e91", "21", "\u897f\u98ce", "\u5fae\u98ce", "19:45"], 42 "day": ["1", "\u591a\u4e91", "35", "\u4e1c\u5357\u98ce", "\u5fae\u98ce", "05:08"], 43 "night": ["1", "\u591a\u4e91", "22", "\u5357\u98ce", "\u5fae\u98ce", "19:45"] 44 } 45 }], 46 。。。。。。 47 }
简单解释下数据:
1.这里只截取了数据的一部分,只保留了我们案例中需要用到的那一小部分,感兴趣的自己去研究吧。
2.显然,这个数据是js中的,json格式数据。
3.本案例中用到的气象数据,是在这个json对象的“weather”属性中。这个属性的值是一个js数组,数组一共有5个元素,每个元素又是一个json对象,每个json对象都代表了一天的天气情况。
三、案例的HTML结构
先看下页面的HTML结构
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>天气预报-hao360接口</title><link rel="stylesheet" href="css/weather.css"> </head> <body><div class="wt_container"><div class="city"><select id="selCity"><option value="101180201">大安阳</option><option value="101010100">北京</option><option value="101180101">郑州</option><option value="101250101">长沙</option><option value="101050101">哈尔滨</option><option value="101130101">乌鲁木齐</option><option value="101280101">广州</option></select><button id="btn">查看天气</button></div><div class="weather"><ul id="wtInfo"><!-- <li><h2>25日</h2><div class="day"><h3>白天天气</h3><p>天气:</p><p>温度</p><p>风向</p><p>风速</p></div><div class="night"><h3>夜间天气</h3><p>天气:</p><p>温度</p><p>风向</p><p>风速</p></div></li> --></ul></div></div> </body> </html>
大家都看得懂,简单说明下:
1.select标签中的每个选项都有一个value值,这个值对应的城市编码,这个编码是国家标准编码,不是自己随便乱写的,我是从百度出来然后写死到页面上的。当然,网上也有关于提供省市编码查询的api,你完全可以根据本案例所讲的方法,结合之前AJAX中讲的省市联动的案例,把这里城市的选择做成活的。我这里为了简单起见,随便从网上扒了几个城市,把城市的code拷贝了一下就写死到HTML了。目的只是为了让例子别太复杂。
2.由于我们拿到的数据是5天的数据,所以我们用一个<ul id = "wtInof">标签来展示所有的查询到的5天的天气,每天的天气用一个li包住。HTML中注释掉的部分就是模拟数据。
我们在js部分,只需要通过jsonp请求道数据,然后按照模拟数据的格式,填充到ul里就行了。
四、案例的js部分
直接看代码
1 <script src="js/jquery-3.3.1.js"></script> 2 <script> 3 function callback(data){ 4 //1.清空ul#wtInfo 5 $("#wtInfo").html(""); 6 //2.呈现数据 7 var wt = data.weather; 8 $.each(wt, function(index, ele){ 9 var date = ele.date; 10 var day = ele.info.day; 11 var night = ele.info.night; 12 var tag = "<li>"; 13 tag += "<h2>" + date + "</h2>"; 14 tag += "<div class='day'>"; 15 tag += "<h3>白天天气</h3>"; 16 tag += "<p>天气:" + day[1] + "</p>"; 17 tag += "<p>温度:" + day[2] + "</p>"; 18 tag += "<p>风向:" + day[3] + "</p>"; 19 tag += "<p>风速:" + day[4] + "</p>"; 20 tag += "</div>"; 21 tag += "<div class='night'>"; 22 tag += "<h3>夜间天气</h3>"; 23 tag += "<p>天气:" + night[1] + "</p>"; 24 tag += "<p>温度:" + night[2] + "</p>"; 25 tag += "<p>风向:" + night[3] + "</p>"; 26 tag += "<p>风速:" + night[4] + "</p>"; 27 tag += "</div>"; 28 tag += "</li>"; 29 $("#wtInfo").append(tag); 30 }); 31 } 32 $(function () { 33 $("#btn").on("click", function () { 34 var cityCode = $("#selCity option:selected").val(); 35 var url = 36 'https://cdn.weather.hao.360.cn/sed_api_weather_info.php?app=hao360&_jsonp=callback&code=' + 37 cityCode; 38 $("body").append($("<script src='" + url + "'><script>")); 39 }) 40 }) 41 </script>
代码解释:
1.这用到了jQuery,所以第1行代码先引入了jQuery包
2.jsonp的原理是通过<script>标签发出请求,而本例中不希望一打开网页就显示某一个城市的天气数据,而是要先选择一个,然后点击查询按钮,才发出请求,得到气象数据, 展示数据。
3.所以我们的思路是:肯定不能在页面上写死那个做jsonp请求的<script src = "......">标签。我们的做法是,当点击按钮时,我们动态的获取到所选select标签中城市的code,然后拼写出待请求的url,最后在文档(document)的body标签底部,动态添加这个做jsonp请求的<script src = "......">标签。
4.代码中定义的function callback(data)函数,就是用来做回调函数的,在这个回调函数中,主要功能就是解析json数据,然后填充到ul中。本身代码逻辑不复杂,就是拼写每个li,以及li里边的各项元素有点费事而已。
五、后记
这个案例,到这里就结束了。我再补充2点:
1.这个案例中需要大量拼写HTML标签代码,这么做是相当费时费力的,而且容易出错;一旦开发一个复杂点的页面,这么做是非常痛苦的。如何改进?我们可以使用模板技术。前端模板插件很多,最流行的前端模板就是art-template.js,大家可以从网上下载。我在这里给出使用该模板改造本例后的js代码,具体这个art-template怎么用,大家看看他官服的demo就一目了然,非常简单。
<script src="js/template.js"></script> <script id="weatherTemp" type="text/html"><li><h2><%= date %></h2><div class="day"><h3>白天天气</h3><% for(var i=1; i < info.day.length; i++){%><p><%= info.day[i]%></p><% }%></div><div class="night"><h3>夜间天气</h3><% for(var i=1; i < info.night.length; i++){%><p><%= info.night[i]%></p><% }%></div></li> </script> <script>function callback(data) {//1.清空ul#wtInfo$("#wtInfo").html("");//2.呈现数据var wt = data.weather;$.each(wt, function (index, ele) {var html = template("weatherTemp", ele)$("#wtInfo").append(html);});}$(function () {$("#btn").on("click", function () {var cityCode = $("#selCity option:selected").val();var url ='https://cdn.weather.hao.360.cn/sed_api_weather_info.php?app=hao360&_jsonp=callback&code=' +cityCode;$("body").append($("<script src='" + url + "'><script>"));})}) </script>
2.如果我们每次都去分析别人的报文,那将是一个非常痛苦的过程。好在现在有专业的,专门提供数据服务的web api提供商,比如“聚合数据”,百度api商店等等,还有很多,大家可以去网上搜索下。其中有免费的,有付费的。比如聚合数据,申请账号是免费的,提供的服务有的免费,有的付费,不过即使是付费的,也可以免费使用1000次,对于我们学习来说1000次够玩了。
转载于:https://www.cnblogs.com/ldq678/p/9748904.html
AJAX(七)jsonp实战--天气预报相关推荐
- 黑马ajax学习笔记02--art-template模板,自动提示,防抖,三级联动,fromData传参及传文件,同源,jsonp,天气预报,CROS,服务器桥接,withCredential跨域登录
1.模板引擎概述 作用:使用模板引擎提供的模板语法,可以将数据和HTML拼接起来 实际上是实现在客户端做数据拼接 art-template模板引擎 官网:http://aui.github.io/ar ...
- ajax的jsonp原理,jsonp 跨域原理和用法(上篇)
出于对网站安全性的要求,两个不同域名的网站之间是不能通过前端技术互相发送请求的.但有时我们又需要使用这样的机制.比如:网站需要制作一个天气预报插件,或者需要开发两个网站,一个供外部用户使用,一个供内部 ...
- 钢七连实战C1-P1:js-python 学习路线
C1-P1课程1,第1节课讲义要点 js-python学习路线和问题 一.学习资源:由基本功,成长为能做各种项目.解决各种问题的软件设计师.架构师. 高级JS--Vue框架 https://www.i ...
- 原生js实现Ajax,JSONP
Ajax内部的几个执行步骤 创建XMLHttpRequest对象(new XMLHttpRequest()) 设置请求头(setRequestHeader) 连接服务器(open()) 设置回调(on ...
- Ajax和Jsonp实践
之前一直使用jQuery的ajax方法,导致自己对浏览器原生的XMLHttpRequest对象不是很熟悉,于是决定自己写下,以下是个人写的deom,发表一下,聊表纪念. Ajax 和 jsonp 的j ...
- Vuejs模拟Ajax请求接口(天气预报API)跨域问题 - 案例篇
vuejs的Ajax跨域请求问题一直都是前端人员开发vue项目进程中经常遇到的不得不解决的热门问题,也是个心病. 首先看一下,页面 报错内容提示: Access to XMLHttpRequest a ...
- 《Web异步与实时交互——iframe AJAX WebSocket开发实战》—— 1.4 内容安排
本节书摘来异步社区<Web异步与实时交互--iframe AJAX WebSocket开发实战>一书中的第1章,第1.4节,作者: 赵振 , 王顺 , 于梦竹 , 李泽 , 侯法超 , 刘 ...
- 原生JavaScript实现AJAX、JSONP
相信大部分前端开发者经常会用jquery的ajax方法与后台进行交互,但是有些时候,我们只需要用到ajax请求数据,而其他的功能几乎用不到,所以就需要知道原生js的ajax请求方法. ajax简介 a ...
- Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化
上一篇:Android 天气APP(十)下拉刷新页面天气数据 逐小时天气预报.UI优化 新版------------------- 一.UI优化 二.逐小时天气预报 ① 添加逐小时天气API ② 使用 ...
- ajax 使用 JSONP 时,只能 GET 不能 POST
前言 ajax不支持用 JSONP(JSON with Padding) 跨域发起 post 请求 html在线运行https://www.runoob.com/runcode ajax 为什么不支持 ...
最新文章
- C# 解决LISTVIEW控件显示数据出现闪屏的问题
- C#对事务的代码封装
- 成本中心和内部订单浅析
- mysql 查询后怎么定位列_MySQL如何定位并优化慢查询sql
- python 递归函数_连载|想用Python做自动化测试?递归函数
- python中下划线开头的命名_Python标识符规则 行与缩进 注释
- smokeping主从同步报错
- MySQL CASE WHEN 根据一个表的字段值不同关联查询两张不同的表【子查询】
- 生命在此定格 路透记者遇难前拍下的最后画面
- 华为手机解锁码计算工具_华为手机强制解锁工具
- java List转Map
- 考勤系统的软件上位机设计
- html把div做成透明背景,DIV半透明层 CSS来实现网页背景半透明
- UMLChina公众号文章精选(20220227更新精选)
- WE出海增长图书馆 | 世界杯豪门面纱下,不容忽视的【增长】沃土
- Android获取硬件设备详细信息
- 程序设计思维 C - 班长竞选 (强连通分量、kosaraju算法)
- BDB(ICCV2019)
- 温度补偿 matlab,基于传感器温度补偿方法的双指数函数模型的温度补偿算法设计...
- 如何用C语言汉字编码输出汉字,【C语言学习】C语言汉字编码。。。C语言中汉字的输入...