为什么是 JSONP
AJAX、JSON、JSONP在 WEB 开发中,经常见到诸如 AJAX、JSON、JSONP 这些名词。三者看起来很像,很多同学尤其是没有系统了解过前端技术体系的同学,平常只是借助类似 JQuery 这类库封装好的函数使用而已,并不了解其原理。但这三种东西具体是什么,有什么关系和区别却常常说不清楚。 接下来,会简要介绍一下三者的的含义,重点阐述 JSONP 的来源和原理,以及为什么 JSONP 不是 AJAX。 AJAX (Asynchronous JavaScript + XML)
异步 JavaScript + XML,是在 2005 年由 Jesse James Garrett 提出的一个术语。 AJAX 并非特指某种技术,描述的是一种结合使用大量已有技术的方式,包括: HTML 或 XHTML,CSS,JavaScript,DOM,XML,XSLT,还有最重要的 XMLHttpRequest 对象. 尽管在 AJAX 中 X 代表 XML,但现在更多的在使用 JSON,因为 JSON 具有很多优势,比如更轻量并且是 JavaScript 的一部分。在 AJAX 模型中 JSON 和 XML 都用于承载信息. JSON(Javascript Object Notation)JSON 是一种轻量级的数据交换格式。由道格拉斯·克罗克福特(Douglas Crockford)在 2012 年发明,并逐渐取代 XML 成为事实上的数据交换格式标准。 JSON 基于 JavaScript Programming Language,Standard ECMA-262 3rd Edition - December 1999的一个子集。但采用完全独立于语言的文本格式,并使用了类似于 C 语言家族的习惯。 在 JSON 中,一共 6 种数据类型:
以及上面的任意组合。 在 JavaScript 中有一个全局对象 JSON,包含两个方法 当然也有人使用 JSONP(JSON with Padding)因为 刚好 但我们要的是数据,而不是一段静态的 JS 代码,怎么办? 这还不简单吗,让服务器动态生成 js ,再把数据放进去不就可以吗。为了区分每一份数据,还需要针对返回的数据做一个标识,其实就是在数据外面包裹一个函数名。 然后需要浏览器端预先设置好这样一个函数,返回的数据就相当于一次执行过程,对获取数据的处理。 总结
举个栗子接下来,用这个简单的示例来说明如何通过 JSONP 的方式获取数据,以及它到底是怎样工作的。 服务器这里使用 Node.js 返回一段简单的数据。 /** * 一个简单的 http 服务器,返回 json 数据 * 跟 Node 主页上的那个经典例子没太大差别 */ var http = require('http'); var urllib = require('url'); var host = '127.0.0.1'; var port = 9999; var data = {'name': 'Mirreal','age': '24'}; http.createServer(function(req,res) { var params = urllib.parse(req.url,true); if (params.query && params.query.callback) { var str = params.query.callback + '(' + JSON.stringify(data) + ')'; // jsonp res.writeHead(200,{ 'Content-Type': 'application/javascript' }); res.end(str); } else { res.end(JSON.stringify(data)); // 普通的json } }).listen(port,host,function() { console.log('server is listening on port ' + port); }); 浏览器// zepto 的写法 $.ajax({ type: 'GET',url: 'http://127.0.0.1:9999',data: { _input_charset: 'utf-8' },dataType: 'jsonp',timeout: 300,context: $('body'),success: function(data){ console.log(data) },error: function(xhr,type) { console.log('Ajax error!') } }); 这样就很轻松的通过 JSONP 的方式获取到数据,我们似乎也不需要关心里面究竟是怎么一回事。但有时候肯能会有人问起:“为什么 jsonp 不能使用 POST 方法”的问题,其实稍微了解一下 JSONP 的原理,这种问题完全就不存在了。 虽然像 JQuery 这类库将 JSONP 封装到 对 JSONP 的简单封装/** * 对 JSONP 的一种简单封装 * * @param {Object} options * @returns null */ function getJsonp(options) { var callbackName = options.callbackName; var url = options.url; var scriptElem = document.createElement('script'); scriptElem.setAttribute('src',url + '?callback=' + callbackName); scriptElem.onload = function(e) { delete window[callbackName]; this.parentNode.removeChild(this); }; scriptElem.onerror = function(e) { console.log(e,'load error'); delete window[callbackName]; this.parentNode.removeChild(this); }; window[callbackName] = options.success; // 调用 document.querySelector('head').appendChild(scriptElem); } 这段代码对 JSONP 进行一层简单包装,调用也很简单: getJsonp({ 'url': 'http://127.0.0.1:9999/','callbackName': 'log','success': function(data) { console.log('我是回调函数,我拿到数据了',data); } }); 看上去代码还挺长的,实际上核心代码不多,分三步: 1.创建一个
|