一、案例

  本次要做的案例的是使用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实战--天气预报相关推荐

  1. 黑马ajax学习笔记02--art-template模板,自动提示,防抖,三级联动,fromData传参及传文件,同源,jsonp,天气预报,CROS,服务器桥接,withCredential跨域登录

    1.模板引擎概述 作用:使用模板引擎提供的模板语法,可以将数据和HTML拼接起来 实际上是实现在客户端做数据拼接 art-template模板引擎 官网:http://aui.github.io/ar ...

  2. ajax的jsonp原理,jsonp 跨域原理和用法(上篇)

    出于对网站安全性的要求,两个不同域名的网站之间是不能通过前端技术互相发送请求的.但有时我们又需要使用这样的机制.比如:网站需要制作一个天气预报插件,或者需要开发两个网站,一个供外部用户使用,一个供内部 ...

  3. 钢七连实战C1-P1:js-python 学习路线

    C1-P1课程1,第1节课讲义要点 js-python学习路线和问题 一.学习资源:由基本功,成长为能做各种项目.解决各种问题的软件设计师.架构师. 高级JS--Vue框架 https://www.i ...

  4. 原生js实现Ajax,JSONP

    Ajax内部的几个执行步骤 创建XMLHttpRequest对象(new XMLHttpRequest()) 设置请求头(setRequestHeader) 连接服务器(open()) 设置回调(on ...

  5. Ajax和Jsonp实践

    之前一直使用jQuery的ajax方法,导致自己对浏览器原生的XMLHttpRequest对象不是很熟悉,于是决定自己写下,以下是个人写的deom,发表一下,聊表纪念. Ajax 和 jsonp 的j ...

  6. Vuejs模拟Ajax请求接口(天气预报API)跨域问题 - 案例篇

    vuejs的Ajax跨域请求问题一直都是前端人员开发vue项目进程中经常遇到的不得不解决的热门问题,也是个心病. 首先看一下,页面 报错内容提示: Access to XMLHttpRequest a ...

  7. 《Web异步与实时交互——iframe AJAX WebSocket开发实战》—— 1.4 内容安排

    本节书摘来异步社区<Web异步与实时交互--iframe AJAX WebSocket开发实战>一书中的第1章,第1.4节,作者: 赵振 , 王顺 , 于梦竹 , 李泽 , 侯法超 , 刘 ...

  8. 原生JavaScript实现AJAX、JSONP

    相信大部分前端开发者经常会用jquery的ajax方法与后台进行交互,但是有些时候,我们只需要用到ajax请求数据,而其他的功能几乎用不到,所以就需要知道原生js的ajax请求方法. ajax简介 a ...

  9. Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化

    上一篇:Android 天气APP(十)下拉刷新页面天气数据 逐小时天气预报.UI优化 新版------------------- 一.UI优化 二.逐小时天气预报 ① 添加逐小时天气API ② 使用 ...

  10. ajax 使用 JSONP 时,只能 GET 不能 POST

    前言 ajax不支持用 JSONP(JSON with Padding) 跨域发起 post 请求 html在线运行https://www.runoob.com/runcode ajax 为什么不支持 ...

最新文章

  1. C# 解决LISTVIEW控件显示数据出现闪屏的问题
  2. C#对事务的代码封装
  3. 成本中心和内部订单浅析
  4. mysql 查询后怎么定位列_MySQL如何定位并优化慢查询sql
  5. python 递归函数_连载|想用Python做自动化测试?递归函数
  6. python中下划线开头的命名_Python标识符规则 行与缩进 注释
  7. smokeping主从同步报错
  8. MySQL CASE WHEN 根据一个表的字段值不同关联查询两张不同的表【子查询】
  9. 生命在此定格 路透记者遇难前拍下的最后画面
  10. 华为手机解锁码计算工具_华为手机强制解锁工具
  11. java List转Map
  12. 考勤系统的软件上位机设计
  13. html把div做成透明背景,DIV半透明层 CSS来实现网页背景半透明
  14. UMLChina公众号文章精选(20220227更新精选)
  15. WE出海增长图书馆 | 世界杯豪门面纱下,不容忽视的【增长】沃土
  16. Android获取硬件设备详细信息
  17. 程序设计思维 C - 班长竞选 (强连通分量、kosaraju算法)
  18. BDB(ICCV2019)
  19. 温度补偿 matlab,基于传感器温度补偿方法的双指数函数模型的温度补偿算法设计...
  20. 如何用C语言汉字编码输出汉字,【C语言学习】C语言汉字编码。。。C语言中汉字的输入...

热门文章

  1. 【JS继承】什么是JS继承?
  2. cmd中start 命令用法
  3. 桌面CPU性能排行榜
  4. RS法计算Hurst指数
  5. 迷你博客的少年烦恼:Twitter的中国效仿者
  6. 计算机电子贺卡制作圣诞节,圣诞节电子贺卡怎么制作?
  7. ubuntu流量监控_ubuntu 流量监控
  8. (PDF目录)自动生成PDF书签目录
  9. 扁平化设计(Flat Design)
  10. TOM邮箱6.0版新功能体验—全新的交互设计