npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sunmi/request

v1.0.6

Published

wrapped fetch method

Downloads

6

Readme

简介

基于fetch的使用封装,借鉴Axios的api,用于网络请求

支持 browser端 和 node端 使用

安装

通过npm:

npm i @sunmi/request

浏览器引用:

<!-- 不支持fetch的浏览器需要polyfill -->
<!-- <script src="/path/to/whatwg-fetch.js" /> -->
<script src="/path/to/@sunmi/request/dist/index.js" />
<!-- 通过全局对象 request 使用 -->

API

基本使用

  • request(config)
  • request(url[, config])

创建实例

  • request.create(config)

快捷方法

  • request.get(url[, params[, config]])
  • request.head(url[, params[, config]])
  • request.delete(url[, params[, config]])
  • request.post(url[, data[, config]])
  • request.put(url[, data[, config]])
  • request.patch(url[, data[, config]])

可访问属性

  • request.defaults
  • request.interceptors

配置

{
    // 请求服务器url
    url?: string;
    // 自动加载 url 前面,除非 url 是绝对地址
    baseURL?: string;
    // 通过url传递的参数
    params?: object | null;
    // 将params序列化的函数
    paramsSerializer?: (params: object) => string;
    // 请求体数据,最终用于body字段的值,仅body未传值时生效,仅用于 POST、PUT、PATCH
    data?: object | null;
    // 请求体数据转换为body支持的类型(默认转换为URLSearchParams),与参数data配合使用,仅用于 POST、PUT、PATCH
    transformData?: (data: object) => BodyInit;
    // 在发送之前,修改请求体数据的钩子,仅用于 POST、PUT、PATCH
    beforeRequest?: Array<(body: BodyInit) => BodyInit>;
    // 在请求返回,传递给 then/catch 前,修改响应数据的钩子
    afterResponse?: Array<(res: Response) => Response>;
    // [未实现] 请求超时的毫秒数(0表示无超时),如果超时将reject一个Error({ type: 'RequestTimeout' })
    timeout?: number;
    // 响应数据类型,默认为json,并对象化处理, 取值 json、text、blob、arraybuffer、''
    responseType?: XMLHttpRequestResponseType;

    /** 以下是 fetch 原生支持的参数 **/
    // 参考:https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
    method?: string;
    headers?: HeadersInit;
    body?: BodyInit | null;
    mode?: RequestMode;
    credentials?: RequestCredentials;
    cache?: RequestCache;
    redirect?: RequestRedirect;
    referrer?: string;
    referrerPolicy?: ReferrerPolicy;
    integrity?: string;
}

使用示例

直接使用 fetch 发送请求,响应数据为json格式字符串,如下

// (1) GET
const params = {
  key: 'key',
  name: 'name'
};
const queryString = qs.stringify(params, { arrayFormat: "brackets" });

fetch(`http://domain.com/webapi/some/action?${queryString}`, {
  method: 'GET'
})
.then(res=>res.json())
.then(res=>{})
.catch(e=>{})

// (2) POST
const data = {
  key: 'key',
  name: 'name'
};
const formdata = new URLSearchParams();
Object.keys(data).map(key=>{
  formdata.append(key, data[key])
})

fetch(`http://domain.com/webapi/some/action`, {
  method: 'POST',
  body: formdata
})
.then(res=>res.json())
.then(res=>{})
.catch(e=>{})

使用 request 来实现上述fetch操作

// (1) GET
request.get(
  'http://domain.com/webapi/some/action', {
  key: 'key',
  name: 'name'
})
.then(res=>{})
.catch(e=>{})

// (2) POST
request.post('http://domain.com/webapi/some/action', {
  key: 'key',
  name: 'name'
})
.then(res=>{})
.catch(e=>{})

request.create

request可直接使用发起请求,也可以通过create方法,创建使用指定配置的实例,实例将拥有 request 的所有方法。

通常使用 create 方法来创建使用不同配置的实例,避免每次请求是重复传递配置参数

配置生效顺序:默认配置 < create创建实例的配置 < 请求方法传入的配置

const rq = request.create({
  baseURL: 'http://domain.com'
})

// 发起上述 (1)的GET 请求
rq.get('/webapi/some/action', {
  key: 'key',
  name: 'name'
})
.then(res=>{})
.catch(e=>{})

// 发起上述 (2)的POSTT 请求
rq.post('/webapi/some/action', {
  key: 'key',
  name: 'name'
})
.then(res=>{})
.catch(e=>{})

request.get

request.get(url[, params[, config]])

get 请求的快捷方法。与之相关的配置参数有 paramsparamsSerializer

import qs from 'qs';

const rq = request.create({
  baseURL: 'http://domain.com',
  paramsSerializer: function(params) {
    return qs.stringify(params, { arrayFormat: 'brackets' })
  }
});

rq.get(
  '/webapi/some/action',
  { key: 'key', name: 'name' }
)
.then(res=>{})
.catch(e=>{})

// 等同于
request.get('/webapi/some/action', null, {
  baseURL: 'http://domain.com',
  params: { key: 'key', name: 'name' }
})

配置参数 paramsSerializer 的默认值,是对 qs.stringify(params, { arrayFormat: 'brackets' }) 的实现

request.head

request.head(url[, params[, config]])

使用参数同 request.get

request.delete

request.delete(url[, params[, config]])

使用参数同 request.get

request.post

request.post(url[, data[, config]])

post 请求的快捷方法。与之相关的配置参数有 datatransformDatabeforeRequest, body

/**
 * 1. 发送URLSearchParams数据
 */
request.post('http://domain.com/webapi/some/action', {
  key: 'key',
  name: 'name'
})
.then(res=>{})
.catch(e=>{})

/**
 * 2. 如果需要发送formdata格式数据
 */
const rq = request.create({
  baseURL: 'http://domain.com',
  transfromData: function(data){
    const formdata = new FormData();
    Object.keys(data).map(key=>{
      formdata.append(key, data[key])
    })
    // 这里甚至可以添加额外的数据,比如给每个请求添加身份token
    return formdata
  }
})

rq.post('/webapi/some/action', {
  key: 'key',
  name: 'name'
})
.then(res=>{})
.catch(e=>{})

/**
 * 3. 如果发送请求前需要对body做一些处理,执行顺序在tansformData之后
 */
request.post('http://domain.com/webapi/some/action', {
  key: 'key',
  name: 'name'
}, {
  // 由于data默认转换类型为URLSearchParams,假设服务端现在需要FormData格式
  beforeRequest: [
    function(body) {
      const formdata = new FormData()
      body.keys().map(key=>{
        formdata.append(key, body.get(key))
      })
      return formdata
    }
  ]
})
.then(res=>{})
.catch(e=>{})

/**
 * 4. data和transformData用于生成body,如果配置参数传递了body,则直接以body作为请求体
 */
const formdata = new FormData();
formdata.append('key', 'key2')

request.post('http://domain.com/webapi/some/action', {
  key: 'key',
  name: 'name'
}, {
  body: formdata
})
.then(res=>{})
.catch(e=>{})
// 最终发往服务器的数据是 { key: 'key2' }

配置参数 transform 的默认值,是一个将 data对象 转化为 URLSearchParams 类型的函数

request.put

request.put(url[, params[, config]])

使用参数同 request.post

request.patch

request.patch(url[, params[, config]])

使用参数同 request.post

拦截器

在请求或响应被 then 或 catch 处理前拦截它们,处理后返回一个promise

// 添加请求拦截器
request.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
request.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

如果希望在使用后移除拦截器

const myInterceptor = request.interceptors.request.use(function () {/*...*/});
request.interceptors.request.eject(myInterceptor);

使用create创建的request实例,也可以添加拦截器

const rq = request.create(config)
rq.interceptors.request.use(function(){/**/})

对于fetch,仅当遇到网络错误时,才会reject,HTTP 404 状态并不被认为是网络错误;而对于实际业务场景可能会有如下情况

  • 除了HTTP 200其余一概视为错误
  • 给每个请求的头部统一加上身份authorization
  • 根据response中的某些字段来判断结果是否正确
  • ...

此时就可以使用拦截器来完成这一处理

/**
 * 给请求头添加authorization
 */
request.interceptors.request.use(function(config) {
  const headers = new Headers();
  headers.append('authorization', 'sssssss')
  config.headers = headers
  return config
}, function(err){
  return Promise.reject(err);
})

/**
 * 如响应结果
 * 成功:{ code: 200, data: { ... }, msg: '' }
 * 失败:{ code: 400, data: null, msg: 'error' }
 */
request.interceptors.response.use(function(response) {
  if(response.code === 200) {
    return response
  } else {
    return Promise.reject(response);
  }
}, function() {
  return Promise.reject(err);
})