NPM的jsonp模块用法

方式:npm/cnpm i jsonp -S    /       yarn add jsonp -S

先贴上官方源码

/**
 * Module dependencies
 */

var debug = require('debug')('jsonp');

/**
 * Module exports.
 */

module.exports = jsonp;

/**
 * Callback index.
 */

var count = 0;

/**
 * Noop function.
 */

function noop(){}

/**
 * JSONP handler
 *
 * Options:
 *  - param {String} qs parameter (`callback`)
 *  - prefix {String} qs parameter (`__jp`)
 *  - name {String} qs parameter (`prefix` + incr)
 *  - timeout {Number} how long after a timeout error is emitted (`60000`)
 *
 * @param {String} url
 * @param {Object|Function} optional options / callback
 * @param {Function} optional callback
 */

function jsonp(url, opts, fn){
  if ('function' == typeof opts) {
    fn = opts;
    opts = {};
  }
  if (!opts) opts = {};

  var prefix = opts.prefix || '__jp';

  // use the callback name that was passed if one was provided.
  // otherwise generate a unique name by incrementing our counter.
  var id = opts.name || (prefix + (count++));

  var param = opts.param || 'callback';
  var timeout = null != opts.timeout ? opts.timeout : 60000;
  var enc = encodeURIComponent;
  var target = document.getElementsByTagName('script')[0] || document.head;
  var script;
  var timer;


  if (timeout) {
    timer = setTimeout(function(){
      cleanup();
      if (fn) fn(new Error('Timeout'));
    }, timeout);
  }

  function cleanup(){
    if (script.parentNode) script.parentNode.removeChild(script);
    window[id] = noop;
    if (timer) clearTimeout(timer);
  }

  function cancel(){
    if (window[id]) {
      cleanup();
    }
  }

  window[id] = function(data){
    debug('jsonp got', data);
    cleanup();
    if (fn) fn(null, data);
  };

  // add qs component
  url += (~url.indexOf('?') ? '&' : '?') + param + '=' + enc(id);
  url = url.replace('?&', '?');

  debug('jsonp req "%s"', url);

  // create script
  script = document.createElement('script');
  script.src = url;
  target.parentNode.insertBefore(script, target);

  return cancel;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

md文件,支持npm等多种安装安装方式。

 mudule.export = jsonp//将jsonp函数导出去,供其他模块调用
  • 1

安装node.js的debug模块

var debug = require('debug')('jsonp');
//当般在nodejs需要进行调试的时候,可以使用console.log()方法来将调试信息输出到控制台,当发布到生产环境的时候,需要将这些调试信息都注释掉,为了方便切换而不需要改动程序代码,可以使用nodejs的debug模块,简单来说就是用来向控制台抛出错误信息的。
eg:
        debug('jsonp got', data);
  • 1
  • 2
  • 3
  • 4
  • 5

关键函数jsonp函数

   接受三个参数,分别是url,opts,fn. 
   url:请求地址的url,eg:http://freegeoip.net/json/?callback=handleResponse 
   opts:有如下四个可选参数 
     * params  与后端约定请求的字段名称,默认是callback 
     * timeout  指定请求响应时间,过多长时间之后显示请求超时 
     * prefix   指定回调函数params的回调句柄前缀,默认为__jp,一般都是默认的,基本用不到 
     * name 指定回调函数的句柄,默认为’_jp${number++}’,一般都是默认的,基本用不到 
   fn 请求事件的回调函数,负责接受data响应数据和请求失败的err信息。

初始化参数

function jsonp(url, opts, fn){
  // 对于两个参数,若不写opts,内部会将函数继续赋给fn
  if ('function' == typeof opts) {
    fn = opts;
    opts = {};
  } 

  // 判断opts是否存在,若不存在,将opts设置空对象
  if (!opts) opts = {}; 

  // 默认回调函数句柄为__jp
  var prefix = opts.prefix || '__jp'; 

  // 默认回调函数的句柄为__jp+数字  count默认为0
  var id = opts.name || (prefix + (count++)); 

  // 设定和函数的key:value,默认为'callback:__jp01'
  var param = opts.param || 'callback'; 

  // 设定请求响应时间,若没有设置,则默认为6秒
  var timeout = null != opts.timeout ? opts.timeout : 60000; 
  var enc = encodeURIComponent; 

  // 捕获dom元素
  var target = document.getElementsByTagName('script')[0] || document.head; 

  // 声明script和timer,script是后面document.createElement出来的,timer是定时器
  var script = null;
  var timer = null;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

url字符串拼接和script脚本dom操作

  // 检测是url是否有参数,如果有参数的话,也有传进来的param参数的话,那就把参拼接到url后面,而后面的enc(id)值就是key:value索要解析到的值,服务端进行**params.opts.param**进行解析调用下面这句id的方法
  url += (~url.indexOf('?') ? '&' : '?') + param + '=' + enc(id);

  // 防止拼接错误出现"?&",然后进行替换
  url = url.replace('?&', '?');

  // 方便调试,这个可以将url console.log()到控制台上
  debug('jsonp req "%s"', url);

  // 创建<script>标签,不受限制的从其它域加载资源
  script = document.createElement('script'); 
  script.src = url; 

  // 插入到head节点或者第一个<script>节点的前面
  target.parentNode.insertBefore(script, target);

  return cancel;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

方法的调用和事件释放

// 进行超时设置,如果超时,那么清除掉原有创建的<script>标签,并且将window[id]=noop(空对象),终止timer定时器,再之后抛出错误
  if (timeout) {
    timer = setTimeout(function(){
      cleanup();
      if (fn) fn(new Error('Timeout'));
    }, timeout);
  }


  function cleanup(){
    if (script.parentNode) script.parentNode.removeChild(script);
    window[id] = noop;
    if (timer) clearTimeout(timer);
  }
// 在引入jsonp模块后,取消对jsonp的调用,但引用模块值外就得这样写 eg:jsonp(yrl,opts,fn)()
  function cancel(){
    if (window[id]) {
      cleanup();
    }
  }

  // 服务端解析params.param进行调用函数
  window[id] = function(data){
    debug('jsonp got', data);
    // 恢复初始值
    cleanup();
    //返回数据
    if (fn) fn(null, data);
  };

猜你喜欢

转载自blog.csdn.net/zuggs_/article/details/80763562
今日推荐