js简单的网络请求封装

nodejs发送请求

下面代码参考的nodejs的版本10.15.3,建议安装10.15.3或更高的版本,简单的封装了getpostjsonp三种请求方式

import https from 'https'
import http from 'http'
import qs from 'querystring'


const getReqType = url => {
  return url.startsWith('https://') ? https : http
}


export const getReq = (url, params, options = {}) => (new Promise((resolve, reject) => {
  let request = getReqType(url)
  let keys = Object.keys(params)
  url = keys.length ? (url + (url.indexOf('?') > -1 ? '&' : '?') + qs.stringify(params).replace(/\?$/g, '')) : url
  request.get(url, options, res => {
    var data = ''
    res.on('data', (chunk) => {
      data += chunk;
    })
    res.on('end', () => {
      resolve(data)
    })
  }).on('error', err => {
    reject(err)
  })
}))

export const postReq = (url, body, options = {}) => (new Promise((resolve, reject) => {
  let request = getReqType(url)
  let content = qs.stringify(body)
  options.headers = options.headers ? options.headers['content-type'] ? options.headers : {
    ...options.headers,
    'content-type': 'application/x-www-form-urlencoded'
  } : {
    'content-type': 'application/x-www-form-urlencoded'
  }
  options.headers['Content-Length'] = Buffer.byteLength(content, 'utf8')

  let req = request.request(url, {
    ...options,
    method: 'POST',
  }, res => {
    res.setEncoding('utf8');
    var data = ''
    res.on('data', (chunk) => {
      data += chunk
    })
    res.on('end', () => {
      resolve(data)
    })
  }).on('error', err => {
    reject(err)
  })
  req.write(qs.stringify(content))
  req.end()
}))

export const jsonp = async (url, params) => {
  let callback = '_cb'
  if (params.callback) {
    callback = params.callback
  }
  let res
  const data = await getReq(url, { ...params,
    callback
  })
  eval(`function ${callback}(data){res=data}   ` + data)
  return res
}

export default {
  get: getReq,
  post: postReq,
  jsonp
}

调用方法

import request from './req'
async function getData() {
  const res = await request.get('http://localhost:3000/get', {
    name: 'shibin'
  })
}
getData()

浏览器发送请求

下面是使用es5封装的

var  _jpid = 0

function Request() {
  var util = {}
  util.get = util.GET = function(url, params, cb) {
    this._formatRequest(url, 'GET', params, db)
  }
  util.post = util.POST = function(url, data, cb) {
    this._formatRequest(url, 'POST', data, cb)
  }
  util._formatRequest = function(url, type, data, cb) {
    util.ajax({
      url: url,
      type: type,
      data: data,
      success: function(res) {
        cb(res)
      },
      error: function(err) {
        cb('', err)
      }
    })
  }
  util.ajax = function(opt) {
    var xhr = XMLHttpRequest ? new XMLHttpRequest : new ActiveXObject
    var type = opt.type.toUpperCase(),
      data = opt.data,
      url = opt.url,
      dataArr = []
    for (var k in data) {
      if (typeof data[k] !== 'undefined') {
        dataArr.push(k + '=' + data[k])
      }
    }
    if (type === 'GET') {
      url = dataArr.length ? (url + (url.indexOf('?') > -1 ? '&' : '?') + dataArr.join('&')).replace(/\?$/g, '') : url
      xhr.open(type, url, true)
      for (var k in opt.headers) {
        xhr.setRequestHeader(k, opt.headers)
      }
      xhr.send()
    } else if (type === 'POST') {
      xhr.open(type, url, true)
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      for (var k in opt.headers) {
        xhr.setRequestHeader(k, opt.headers)
      }
      xhr.send(dataArr.join('&'))
    } else if (type === "JSONP") {
      util.jsonp(opt)
    }
    xhr.onload = function() {
      var res = JSON.parse(xhr.responseText)
      if (xhr.status === 200 || xhr.status === 304) {
        if (opt.success && opt.success instanceof Function) {
          var res = JSON.parse(xhr.responseText)
          if (xhr.status === 200 || xhr.status === 304) {
            opt.success.call(xhr, res)
          } else {
            opt.error.call(xhr, res)
          }
        }
      } else {
        if (opt.error && opt.error instanceof Function) {
          opt.error.call(xhr, res)
        }
      }
    }
  }

  util.inQueryUrl = function(url, data) {
    if (!data) {
      return url
    }
    var str = url + '?'
    for (var k in data) {
      var item = k + '=' + data[k] + '&'
      str += item
    }
    str = str.slice(0, str.length - 1)
    return str
  }
  util.jsonp = function(opt) {
    var callbackName = opt.jsonp || ((opt.data && opt.data.callback) ? opt.data.callback : '_jp' + _jpid++)
    opt.data.callback = callbackName
    var head = document.getElementsByTagName('head')[0]
    var data = formatParams(opt.data)
    var script = document.createElement('script')
    head.appendChild(script)
    window[callbackName] = function(json) {
      head.removeChild(script);
      clearTimeout(script.timer);
      window[callbackName] = null;
      if (opt.success && opt.success instanceof Function) {
        opt.success.call(window, json)
      }
    }
    script.src = opt.url + '?' + data
    if (opt.time) {
      script.timer = setTimeout(function() {
        window[callbackName] = null;
        head.removeChild(script);
        opt.error && opt.error({
          message: '超时'
        });
      }, time)
    }
  }
  return util
}

function formatParams(data) {
  var arr = [];
  for (var name in data) {
    arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
  };
  // 添加一个随机数,防止缓存
  arr.push('v=' + random());
  return arr.join('&');
}
// 获取随机数
function random() {
  return Math.floor(Math.random() * 10000 + 500);
}

调用方法

var $=new Request()
$.ajax({
  url:'http://localhost:3000/post',
  type:'post',
  data:{
    name:'shibin'
  },
  success:function(res){
    console.log(res)
  },
  error:function(err){
    console.log(err);
  }
})

 $.get('http://localhost:3000/get', {
    name: 'shibin'
 }, function(res, err) {
    if (res) {
     console.log(res)
   } else {
     console.log(err);
   }
})

下面是基于es6封装的

var __jpid = 0

class Request {
  get(url, params) {
    return new Promise((resolve, reject) => {
      this._formatRequest(url, 'GET', params, resolve)
    })
  }
  post(url, params) {
    return new Promise((resolve, reject) => {
      this._formatRequest(url, 'POST', params, resolve)
    })
  }
  _formatRequest(url, type, data, resolve) {
    this.ajax({
      url: url,
      type: type,
      data: data
    }).then(res => {
      resolve(res)
    })
  }
  ajax(opt) {
    return new Promise((resolve, reject) => {
      var xhr = XMLHttpRequest ? new XMLHttpRequest : new ActiveXObject
      var type = opt.type.toUpperCase(),
        data = opt.data,
        url = opt.url,
        dataArr = []
      for (var k in data) {
        if (typeof data[k] !== 'undefined') {
          dataArr.push(k + '=' + data[k])
        }
      }
      if (type === 'GET') {
        url = dataArr.length ? (url + (url.indexOf('?') > -1 ? '&' : '?') + dataArr.join('&')).replace(/\?$/g, '') : url
        xhr.open(type, url, true)
        for (var k in opt.headers) {
          xhr.setRequestHeader(k, opt.headers)
        }
        xhr.send()
      } else if (type === 'POST') {
        xhr.open(type, url, true)
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        for (var k in opt.headers) {
          xhr.setRequestHeader(k, opt.headers)
        }
        xhr.send(dataArr.join('&'))
      } else if (type === 'JSONP') {
        this.jsonp(opt, reject, resolve)
      }
      xhr.onload = function() {
        var res = JSON.parse(xhr.responseText)
        if (xhr.status === 200 || xhr.status === 304) {
          resolve(res)
          if (opt.success && opt.success instanceof Function) {
            opt.success.call(xhr, res)
          }
        } else {
          reject(res)
          if (opt.error && opt.error instanceof Function) {
            opt.error.call(xhr, res)

          }
        }
      }
    })

  }
  jsonp(opt) {
    return new Promise((resolve, reject) => {
      // var callbackName = opt.jsonp;
      var callbackName = opt.jsonp || ((opt.data && opt.data.callback) ? opt.data.callback : '_jp' + __jpid++)
      opt.data.callback = callbackName
      var head = document.getElementsByTagName('head')[0]
      var data = formatParams(opt.data);
      var script = document.createElement('script')
      head.appendChild(script)
      window[callbackName] = function(json) {
        head.removeChild(script);
        clearTimeout(script.timer);
        window[callbackName] = null;
        resolve(json)
        if (opt.success && opt.success instanceof Function) {
          opt.success.call(window, json)
        }
      }
      script.src = opt.url + '?' + data
      if (opt.time) {
        script.timer = setTimeout(function() {
          window[callbackName] = null;
          head.removeChild(script);
          reject({
            message: '超时'
          })
          opt.error && opt.error({
            message: '超时'
          });
        }, time)
      }
    })
  }
}

function formatParams(data) {
  var arr = [];
  for (var name in data) {
    arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
  };
  // 添加一个随机数,防止缓存
  arr.push('v=' + random());
  return arr.join('&');
}
// 获取随机数
function random() {
  return Math.floor(Math.random() * 10000 + 500);
}

调用方法

var $=new Request()
$.ajax({
  url:'http://localhost:3000/post',
  type:'post',
  data:{
    name:'shibin'
  }
}).then(res => {
    console.log(res)
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,485评论 1 45
  • 1.几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构? 基本数据类型:Undefined、Nul...
    极乐君阅读 5,514评论 0 106
  • 一:什么是闭包?闭包的用处? (1)闭包就是能够读取其他函数内部变量的函数。在本质上,闭包就 是将函数内部和函数外...
    xuguibin阅读 9,604评论 1 52
  • AFHTTPRequestOperationManager 网络传输协议UDP、TCP、Http、Socket、X...
    Carden阅读 4,337评论 0 12
  • 前几天刚结束了一年一度的巴菲特股东大会,在这次会议上巴菲特改变了以往的投资思维,开始投资科技型公司(在会上他说到在...
    两粒米阅读 364评论 0 1