JavaScript中模拟实现jsonp


Posted in Javascript onJune 19, 2015
function prescript(s) {
    if (s.cache === undefined) {
      s.cache = false;
    }
    if (s.crossDomain) {
      s.type = "GET";
    }
  }


  function prejsonp(s, originalSettings, jqXHR) {
    // 给回调函数命名
    var callbackName = s.jsonpCallback
    s.url += (/(?:)/.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
    // 脚本执行后使用数据转换器来检索json
    // 提供给代码获取服务器的是据
    s.getData = function() {
      if (!responseContainer) {
        jQuery.error(callbackName + " was not called");
      }
      return responseContainer[0];
    };
    //修改处理机制
    s.dataTypes[0] = "json";
    // 创建一个全局函数
    overwritten = window[callbackName];
    //用来收集服务器给的数据
    window[callbackName] = function() {
      responseContainer = arguments;
    };

    return "script";
  }

  /**
   * jsonp的预先处理
   */
  function inspectPrefiltersOrTransportsA(options, originalOptions, jqXHR) {
    //预处理jsonp
    var dataTypeOrTransport = prejsonp(options, originalOptions, jqXHR)
    //扩充dataTypes
    options.dataTypes.unshift(dataTypeOrTransport);
    //预处理script类型
    prescript(options)
  }


  /**
   * 分发器
   * @return {[type]} [description]
   */
  function inspectPrefiltersOrTransportsB(s, originalOptions, jqXHR) {
    return {
      send: function(_, complete) {
        var script = jQuery("<script>").prop({
          async: true,
          charset: s.scriptCharset,
          src: s.url
        }).on(
          "load error",
          callback = function(evt) {
            script.remove();
            callback = null;
            if (evt) {
              complete()
            }
          }
        );
        //<script async="" src="http://192.168.1.113:8080/github/jQuery/jsonp.php
        document.head.appendChild(script[0]);
      }
    }
  }

  /**
   * 模拟ajax的 jsonp请求
   * @param {[type]} options [description]
   * @return {[type]}     [description]
   */
  function createAjax(options) {

    if (typeof url === "object") {
      options = url;
      url = undefined;
    }

    options = options || {};

    /**
     * 参数
     * jQuery.ajaxSetup 是默认参数
     * @type {[type]}
     */
    var s = jQuery.ajaxSetup({}, options);

    // Deferreds
    // 异步机制
    var deferred = jQuery.Deferred();
    var completeDeferred = jQuery.Callbacks("once memory");

    /**
     * 实际返回的ajax对象
     * @type {Object}
     */
    var jqXHR = {}

    // 把jqXHR对象转化promise对象,?占尤?omplete、success、error方法
    deferred.promise(jqXHR).complete = completeDeferred.add;
    //别名
    jqXHR.success = jqXHR.done;
    jqXHR.error = jqXHR.fail;

    s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(/(?:)/) || [""];

    //预处理
    inspectPrefiltersOrTransportsA(s, options, jqXHR);

    for (i in {
      success: 1,
      error: 1,
      complete: 1
    }) {
      jqXHR[i](s[i]);
    }

    /**
     * 分发器
     */
    transport = inspectPrefiltersOrTransportsB(s, options, jqXHR);

    function done(status, nativeStatusText, responses, headers) {
      console.log(s,s.getData())
    }

    //发送请求
    transport.send(s, done);

    return jqXHR;
  }


  function show(data){
    $('body').append('<li>'+ data +'</li>');
  }

  /**
   * 数据回调接收
   * @return {[type]} [description]
   */
  function flightHandler(){

  }

  $("#test").click(function(){
    //执行一个异步的HTTP(Ajax)的请求。
    var ajax = createAjax({
      url: 'http://192.168.1.113:8080/github/jQuery/jsonp.php',
      data: {
        'action': 'aaron'
      }, // 预传参的数组
      dataType: 'jsonp', // 数据类型
      jsonp: 'callback', // 指定回调函数名,与服务器端接收的一致,并回传回来
      jsonpCallback:flightHandler,
      success: function() {
        show('局部事件success')
      }
    })
  })
Javascript 相关文章推荐
用JavaScript和注册表脚本实现右键收藏Web页选中文本
Jan 28 Javascript
jQuery学习2 选择器的使用说明
Feb 07 Javascript
JS和函数式语言的三特性
Mar 05 Javascript
js判断子窗体是否关闭的方法
Aug 11 Javascript
基于Bootstrap3表格插件和分页插件实例详解
May 17 Javascript
再谈Javascript中的基本类型和引用类型(推荐)
Jul 01 Javascript
JS正则表达式修饰符中multiline(/m)用法分析
Dec 27 Javascript
Bootstrap 3浏览器兼容性问题及解决方案
Apr 11 Javascript
详解VUE 数组更新
Dec 16 Javascript
基于Vue实现关键词实时搜索高亮显示关键词
Jul 21 Javascript
JavaScript中this函数使用实例解析
Feb 21 Javascript
vue-video-player 断点续播的实现
Feb 01 Vue.js
基于jQuery+Cookie实现的防止刷新的在线考试倒计时
Jun 19 #Javascript
MVVM模式中ViewModel和View、Model有什么区别?
Jun 19 #Javascript
JavaScript中数据结构与算法(五):经典KMP算法
Jun 19 #Javascript
使用AngularJS编写较为优美的JavaScript代码指南
Jun 19 #Javascript
javascript格式化日期时间方法汇总
Jun 19 #Javascript
JavaScript中数据结构与算法(四):串(BF)
Jun 19 #Javascript
JavaScript中数据结构与算法(三):链表
Jun 19 #Javascript
You might like
盘点被央视点名过的日本动画电影 一部比一部强
2020/03/08 日漫
无限级别菜单的实现
2006/10/09 PHP
phpexcel导入excel数据使用方法实例
2013/12/24 PHP
php+html5实现无刷新图片上传教程
2016/01/22 PHP
在标题栏显示新消息提示,很多公司项目中用到这个方法
2011/11/04 Javascript
异步javascript的原理和实现技巧介绍
2012/11/08 Javascript
JS的document.all函数使用示例
2013/12/30 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
2014/07/29 Javascript
javascript实现日期格式转换
2014/12/16 Javascript
浅谈json取值(对象和数组)
2016/06/24 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
微信JS-SDK自定义分享功能实例详解【分享给朋友/分享到朋友圈】
2016/11/25 Javascript
微信小程序 数组(增,删,改,查)等操作实例详解
2017/01/05 Javascript
原生JS仿QQ阅读点击展开、收起效果
2017/03/08 Javascript
微信小程序 wx.request方法的异步封装实例详解
2017/05/18 Javascript
Nodejs+express+ejs简单使用实例代码
2017/09/18 NodeJs
解决vue attr取不到属性值的问题
2018/09/18 Javascript
angular学习之动态创建表单的方法
2018/12/07 Javascript
JavaScript数据结构与算法之检索算法实例分析【顺序查找、最大最小值、自组织查询】
2019/02/22 Javascript
vue中利用iscroll.js解决pc端滚动问题
2020/02/15 Javascript
利用React高阶组件实现一个面包屑导航的示例
2020/08/23 Javascript
python 动态获取当前运行的类名和函数名的方法
2014/04/15 Python
python在不同层级目录import模块的方法
2016/01/31 Python
django文档学习之applications使用详解
2018/01/29 Python
Python从Excel中读取日期一列的方法
2018/11/28 Python
基于sklearn实现Bagging算法(python)
2019/07/11 Python
使用 Django Highcharts 实现数据可视化过程解析
2019/07/31 Python
使用Python实现正态分布、正态分布采样
2019/11/20 Python
pandas DataFrame运算的实现
2020/06/14 Python
全球度假村:Club Med
2017/11/27 全球购物
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/01/13 面试题
施工材料员岗位职责
2014/02/12 职场文书
新闻发布会新闻稿
2015/07/17 职场文书
适合青年人白手起家的创业项目分享
2019/08/16 职场文书
Redis6.0搭建集群Redis-cluster的方法
2021/05/08 Redis
gateway与spring-boot-starter-web冲突问题的解决
2021/07/16 Java/Android