借助cryptoJS , jsonp跨域,请求心知天气API ,获取天气信息
之前模仿百度首页,在获取天气信息这一块,比较好奇,就准备尝试着做一下。这一做牵扯出了很多的知识点,于是我在这里记录下来,方便自己,方便别人,也帮心知天气宣传一下,他们的服务做得真的很好http://www.thinkpage.cn/。
接着,往下一翻发现有一句如何使用JSONP方式调用。
于是开启第一部分:
1、jsonp的原理先说概念:jsonp是动态跨域获取数据的一种方式。 下面补充json对象与json字符串互相转换的方法。 字符串转json对象: var obj = str.parseJSON(); //由JSON字符串转换为JSON对象 或者 var obj = JSON.parse(str); //由JSON字符串转换为JSON对象 json对象转字符串: var last=obj.toJSONString(); //将JSON对象转化为JSON字符 或者 var last=JSON.stringify(obj); //将JSON对象转化为JSON字符 1.4、因此,如果我们可以联想到,在前端直接获取不同域的服务器上的数据,可以通过向目标服务器直接请求一个动态js文件回来(该文件一般以json方式为后缀),之所以是动态的,是因为服务器可以将数据填充到动态文件中。 1.5、发送请求时,使用<script>标签引入的文件是通过get方式获取的,而get请求的后面就可以带参数,这里的参数就是回调函数的名字。 1.6、服务器接受到请求之后,分离出回调函数,再将前端所需要的数据封装成一个对象,以参数的形式给到回调函数中,接着请求返回到前端。 // 得到航班信息查询结果后的回调函数 var flightHandler = function(data){ alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。'); }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码) var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 创建script标签,设置其属性 var script = document.createElement('script'); script.setAttribute('src',url); // 把script标签加入head,此时调用开始 document.getElementsByTagName('head')[0].appendChild(script); 当请求到达服务器后,会根据参数,制作一个数据出来。再将这个数据以参数的形式,填充到回调函数的参数中。然后服务器将动态生成的js文件返回。 返回后,回调函数会立即执行。此时我们就达到了跨域从后台获取数据的效果。 2、ajax异步使用jsonp此外,我们还应该知道的是,jQuery也是支持jsonp的,它是通过$.ajax的方式支持jsonp的。 $.ajax({ type: "get",async: false,url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",dataType: "jsonp",cache: true,jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(json){ alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。'); },error: function(){ alert('fail'); } }); 这里要注意以下几点: 2、通过加密的方式获取数据3.1、介绍node使用cryptoJS方式加密数据API中提到采用node.js的crypto模块加密。 var crypto = require("crypto"); var str = "ts=1443079775&ttl=30&uid=U123456789"; var key = "secret"; var result = crypto.createHmac('sha1',key); var final = result.update(str).digest('base64'); console.log(final); 当然也有不用node的测试方法。各位看官可以到https://1024tools.com/hmac 网站中验证上面的数据。 使用require('crypto')调用加密模块 crypto.createHash(algorithm) crypto.createHmac(algorithm,key) hash.digest(encoding='binary') hmac.digest(encoding='binary') 计算所有传入数据的hash摘要。参数encoding(编码方式)可以为'hex','binary' 或者'base64'。
hmac.update(data)
更新hmac的内容为指定的data。当使用流数据时可能会多次调用该方法。
更多内容请参考:http://www.aspzz.cn/article/50668.htm
知道了这一步,我们知道加密的流程是什么样了。不知大家是否注意到例子中有一个ts。 var myDate = new Date(); var ts = myDate.getTime(); //获取当前时间(从1970.1.1开始的毫秒数)参考文章: http://www.cnblogs.com/carekee/articles/1678041.html 3.2、介绍在web前端使用CryptoJS加密数据接下来,问题又来了,那么我怎么将加密方式移植到web页面中去呢?其实呢网上有一个crypto的加密库,它不仅可以在node中使用,也可以在浏览器中以script标签引用的方式使用。下载地址:https://github.com/brix/crypto-js 下面直接写成果,免得大家走弯路。 1、去git上下载crypto-js这个库 <script src="js/core.js"></script> <script src="js/cipher-core.js"></script> <script src="js/enc-base64.js"></script> <script src="js/hmac.js"></script> <script src="js/sha1.js"></script> 可以看到除了两个核心模块,其他的就是我们在加密过程中需要模块。那么接下来,我们就可以在web页面中执行hmac的加密了。str是被加密的字符串,key是密钥。 var result = CryptoJS.HmacSHA1(str,key); var signature = result.toString(CryptoJS.enc.Base64); signature = encodeURI(signature); 4、借助ajax的jsonp方式获取心知天气数据的过程首先,组装加密后的请求: var ts = new Date().getTime(); var str = "ts="+ts+"&ttl=30&uid=U75028BE2C"; //uid需要换成自己账户中的uid var result = CryptoJS.HmacSHA1(str,key); //key需要换成自己账户中的key var signature = result.toString(CryptoJS.enc.Base64); signature = encodeURI(signature); 接着,组装url: var url = "https://api.thinkpage.cn/v3/weather/now.json?location="+ city +"&"+str+"&sig="+signature; 然后,ajax发出请求: $.ajax({ type: "get",cache: false,url: url,//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"showWeather",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(json){ console.log(json); },error: function(){ alert('fail'); } });
至此,在ajax的回调函数中添加业务逻辑代码,整个jsonp跨域获取数据就ok了,接下来本地测试。心知天气官方需要有域名,并且域名绑定账号才能获取数据,否则连接将一定会被禁掉。 我估计是为了盈利的考虑,一个账号绑定一个域名吧。当然这个地方是我整个文章中唯一不能确认的地方,为什么要这么做。如果各位知道的话,请告诉我。不过需要域名,我就给你一个好了。我们不需要自己搭建一个服务器,或者买一个域名,只需要在本地打一个wamp环境,在host文件中将127.0.0.1映射到例如c.test123.com。然后再将这个域名绑定到你注册心知天气的账号上。
绑定过程类似下面的方式:
最后将工程放在wamp的www目录下运行就可以了。 整个文章,有自己思考的部分,也有借鉴别人的部分。总体上记录了个人思考发现的整个过程。这一次好奇,解决了一个又一个的问题,完全搞懂了jsonp。谢谢各位大牛的分享,也感谢心知天气的客服耐心细致的回答,希望他们的公司越做越好。 http://www.thinkpage.cn/doc 这编辑器好难用,看来我以后要用MarkDown写博客了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |