Compare commits
No commits in common. "master" and "v1" have entirely different histories.
180
Readme.md
180
Readme.md
|
@ -1,5 +1,4 @@
|
|||
![downloads](https://img.shields.io/npm/dt/@gm5/response.svg)
|
||||
![version](https://img.shields.io/npm/v/@gm5/response.svg)
|
||||
![module info](https://nodei.co/npm/@gm5/response.png?downloads=true&downloadRank=true&stars=true)
|
||||
|
||||
# @gm5/response
|
||||
|
||||
|
@ -21,8 +20,181 @@ http
|
|||
.createServer((req, res) => {
|
||||
let response = new Response(req, res)
|
||||
|
||||
response.type = 'html'
|
||||
response.body = '<h1>hello world</h1>'
|
||||
// it eq. argument res
|
||||
console.log(response.res)
|
||||
|
||||
response.set('content-type', 'text/html; charset=utf-8')
|
||||
response.end('hello world')
|
||||
})
|
||||
.listen(3000)
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
|
||||
### origin
|
||||
> 返回原始的 request & response 对象.
|
||||
|
||||
|
||||
|
||||
### error(msg[, code])
|
||||
|
||||
* msg `<String>`
|
||||
* code `<Number>` Http状态码 [可选]
|
||||
|
||||
> 在客户端(浏览器)上输出友好的错误信息格式
|
||||
|
||||
```javascript
|
||||
response.error('This is the error code', 500) //
|
||||
response.error(null, 500) // null/empty, it will call the statusText back
|
||||
response.error('Page not Found', 404) //
|
||||
response.error(new Error('Auth denied'), 401) //
|
||||
```
|
||||
|
||||
### status(code)
|
||||
|
||||
* code `<Number>`
|
||||
|
||||
> 设置Http状态码
|
||||
|
||||
```javascript
|
||||
response.setStatus(501) //
|
||||
response.setStatus(200) //
|
||||
```
|
||||
|
||||
### set(key[, val])
|
||||
|
||||
* key `<String>` | `<Object>`
|
||||
* code `<String>` | `<Number>`
|
||||
|
||||
> 设置响应头, 属性字段名不区分大小写
|
||||
|
||||
**相同的字段会被覆盖.**
|
||||
**`content-type`如果没有设置编码时, 会自动设置为utf8**
|
||||
|
||||
```javascript
|
||||
response.set('content-type', 'text/html; charset=utf-8') //
|
||||
response.set('content-type', 'text/html') // 等价于上面的
|
||||
|
||||
response.set({'content-type', 'text/html', foo: 'bar'[, ...]})
|
||||
```
|
||||
|
||||
### append(key, val)
|
||||
|
||||
* key `<String>`
|
||||
* code `<String>` | `<Number>`
|
||||
|
||||
> 设置响应头, 属性字段名不区分大小写。与`set()`的区别时, 这个不会覆盖相同的字段, 而是合并输出。
|
||||
|
||||
```javascript
|
||||
response.append('name', 'foo')
|
||||
response.append('name', 'bar') //客户端能同时看到foo和bar这2个值
|
||||
```
|
||||
|
||||
### get(key)
|
||||
|
||||
* key `<String>`
|
||||
|
||||
> 获取即将要发送到客户端的头信息。
|
||||
|
||||
```javascript
|
||||
response.set('name', 'foo')
|
||||
response.get('name') // foo
|
||||
```
|
||||
|
||||
|
||||
### redirect(url[, f])
|
||||
|
||||
* url `<String>`
|
||||
* f `<Boolean>` 是否永久重定向, 默认否
|
||||
|
||||
> 重定向url.
|
||||
|
||||
```javascript
|
||||
response.redirect('http://test.com/foo')
|
||||
response.redirect('http://test.cn', true)
|
||||
```
|
||||
|
||||
### location(url)
|
||||
|
||||
* url `<String>`
|
||||
|
||||
> 重定向url. 但这是使用前端的方式跳转的.
|
||||
|
||||
```javascript
|
||||
response.location('http://test.com/foo')
|
||||
response.location('/foo')
|
||||
```
|
||||
|
||||
### render(data[, code])
|
||||
|
||||
* data `<String>` | `<Buffer>`
|
||||
* code `<Number>` Http状态码, 默认200
|
||||
|
||||
> 以html形式渲染内容。每次请求只能调用1次。
|
||||
|
||||
|
||||
```javascript
|
||||
let html = fs.readFileSync('./index.html')
|
||||
response.render(html) // send from a html file.
|
||||
|
||||
let txt = '<h1>hello world</h1>'
|
||||
response.render(txt)
|
||||
|
||||
response.render("You're not able to here", 401)
|
||||
```
|
||||
|
||||
### sendfile(target, name)
|
||||
|
||||
* target `<String>` | `<Buffer>` 可以是文件路径, 可以是文本, 可以是Buffer
|
||||
* name `<String>` 要保存的文件名
|
||||
|
||||
> 直接以附件形式响应, 作为文件下载功能.
|
||||
|
||||
```javascript
|
||||
// 不推荐
|
||||
let pic = fs.readFileSync('./boy.jpg')
|
||||
response.sendfile(pic, 'a-little-boy.jpg')
|
||||
|
||||
// 推荐使用
|
||||
response.sendfile('./boy.jpg', 'a-little-boy.jpg')
|
||||
|
||||
response.sendfile('blablabla', 'bb.txt')
|
||||
```
|
||||
|
||||
|
||||
|
||||
### send(code[, msg][, data][, callback])
|
||||
|
||||
* code `<Number>` http状态码
|
||||
* msg `<String>` 错误信息文本
|
||||
* data `<Object>` 响应主体内容, 可以是任意格式
|
||||
* callback `<String>` 以jsonp形式返回对应的callback名
|
||||
|
||||
> 向客户端输出一个json(p), 支持resful api。
|
||||
|
||||
|
||||
```javascript
|
||||
response.send(200, 'ok', { foo: 'bar' })
|
||||
// client will get the content like
|
||||
// '{"code": 200, "msg": "ok", "data": {"foo": "bar"}}'
|
||||
|
||||
response.send(200, 'success', { name: 'foo', age: 16 }, 'blabla')
|
||||
// client will get the content like
|
||||
// 'blabla({"code": 200, "msg": "success", "data": {"name": "foo", "age": 16}})'
|
||||
```
|
||||
|
||||
### end([data])
|
||||
|
||||
* data `<String>` | `<Buffer>` optional
|
||||
|
||||
> 向客户端输出内容。
|
||||
|
||||
|
||||
### cookie(key, value, options)
|
||||
|
||||
* key `<String>`
|
||||
* value `<String>`
|
||||
* options `<Object>` 额外配置[可选]
|
||||
|
||||
> 向客户端写入cookies。
|
274
index.js
274
index.js
|
@ -5,64 +5,12 @@
|
|||
|
||||
import fs from 'iofs'
|
||||
import STATUS_TEXT from './lib/http-code.js'
|
||||
import { MIME_TYPES, CHARSET_TYPES } from './lib/mime-tpyes.js'
|
||||
import { serialize } from './lib/cookie.js'
|
||||
|
||||
export default class Response {
|
||||
#req = null
|
||||
#res = null
|
||||
|
||||
#charset = 'utf-8'
|
||||
status = 200
|
||||
|
||||
#ended = false
|
||||
|
||||
constructor(req, res) {
|
||||
this.#req = req
|
||||
this.#res = res
|
||||
|
||||
this.#ended = !!res.ended
|
||||
}
|
||||
|
||||
get ended() {
|
||||
return this.#ended
|
||||
}
|
||||
|
||||
set charset(v) {
|
||||
this.#charset = v || 'utf-8'
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this.#res.getHeader('content-type')
|
||||
}
|
||||
|
||||
set type(v) {
|
||||
let mime = MIME_TYPES[v] || MIME_TYPES.stream
|
||||
mime += CHARSET_TYPES[v] ? '; charset=' + this.#charset : ''
|
||||
this.set('Content-Type', mime)
|
||||
}
|
||||
|
||||
set length(val) {
|
||||
this.set('Content-Length', val)
|
||||
}
|
||||
|
||||
set body(buf = null) {
|
||||
if (this.#ended) {
|
||||
return
|
||||
}
|
||||
|
||||
this.#ended = true
|
||||
this.#res.writeHead(this.status, STATUS_TEXT[this.status])
|
||||
this.#res.end(buf)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存时长, 单位秒
|
||||
*/
|
||||
set expires(time = 3600) {
|
||||
let t = new Date(Date.now() + time * 1000)
|
||||
this.set('Expires', t.toGMTString())
|
||||
this.set('Cache-Control', 'max-age=' + time)
|
||||
this.origin = { req, res }
|
||||
this.rendered = !!res.rendered
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,14 +19,20 @@ export default class Response {
|
|||
* @param {String} msg [错误提示信息]
|
||||
*/
|
||||
error(msg, code = 500) {
|
||||
if (this.#ended) {
|
||||
if (this.rendered) {
|
||||
return
|
||||
}
|
||||
msg = msg || STATUS_TEXT[code]
|
||||
|
||||
this.status = code
|
||||
this.type = 'html'
|
||||
this.body = `<fieldset><legend>Http Status: ${code}</legend><pre>${msg}</pre></fieldset>`
|
||||
this.status(code)
|
||||
this.set('Content-Type', 'text/html; charset=utf-8')
|
||||
this.end(
|
||||
`<fieldset><legend>Http Status: ${code}</legend><pre>${msg}</pre></fieldset>`
|
||||
)
|
||||
}
|
||||
|
||||
status(code = 404) {
|
||||
this.statusCode = code
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,118 +41,70 @@ export default class Response {
|
|||
* @param {Boolean} f [是否永久重定向]
|
||||
*/
|
||||
redirect(url, f = false) {
|
||||
if (this.#ended) {
|
||||
if (this.rendered) {
|
||||
return
|
||||
}
|
||||
if (!/^(http[s]?|ftp):\/\//.test(url)) {
|
||||
url = '//' + url
|
||||
}
|
||||
this.set('Location', url)
|
||||
this.status = f ? 301 : 302
|
||||
this.body = null
|
||||
this.status(f ? 301 : 302)
|
||||
this.end('')
|
||||
}
|
||||
|
||||
/**
|
||||
* [location 页面跳转(前端的方式)]
|
||||
*/
|
||||
location(url) {
|
||||
if (this.#ended) {
|
||||
var html = `<html><head><meta http-equiv="refresh" content="0;url=${url}"></head></html>`
|
||||
if (this.rendered) {
|
||||
return
|
||||
}
|
||||
let html = `<html><head><meta http-equiv="refresh" content="0;url=${url}"></head></html>`
|
||||
this.render(html)
|
||||
}
|
||||
|
||||
// 以html格式向前端输出内容
|
||||
render(data, code) {
|
||||
if (this.#ended) {
|
||||
if (this.rendered) {
|
||||
return
|
||||
}
|
||||
if (code) {
|
||||
this.status = code
|
||||
}
|
||||
data += ''
|
||||
data = data || STATUS_TEXT[this.status]
|
||||
this.type = 'html'
|
||||
this.length = Buffer.byteLength(data)
|
||||
|
||||
this.body = data
|
||||
data = data || STATUS_TEXT[code]
|
||||
this.set('Content-Type', 'text/html')
|
||||
this.set('Content-Length', Buffer.byteLength(data))
|
||||
if (code) {
|
||||
this.status(code)
|
||||
}
|
||||
this.end(data)
|
||||
}
|
||||
|
||||
// 文件下载
|
||||
sendfile(target, filename = 'untitled', expires = 3600) {
|
||||
if (this.#ended) {
|
||||
sendfile(target, filename) {
|
||||
if (this.rendered) {
|
||||
return
|
||||
}
|
||||
let data, start, end
|
||||
var data
|
||||
|
||||
if (!this.type) {
|
||||
this.status = 206
|
||||
this.type = 'stream'
|
||||
this.set('Content-Disposition', `attachment;filename="${filename}"`)
|
||||
this.set('Content-Type', 'application/force-download')
|
||||
this.set('Accept-Ranges', 'bytes')
|
||||
|
||||
let range = this.#req.headers['range'] || ''
|
||||
if (range) {
|
||||
range = range.replace('bytes=', '')
|
||||
if (range.includes(',')) {
|
||||
// 多重范围的range请求, 暂时不支持, 直接返回整个文件
|
||||
} else {
|
||||
range = range.split('-').map(n => +n)
|
||||
;[start, end] = range
|
||||
|
||||
if (end === 0) {
|
||||
end = void 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.expires = expires
|
||||
this.set('Content-Disposition', `attachment;filename="${filename}"`)
|
||||
|
||||
if (Buffer.isBuffer(target)) {
|
||||
data = target
|
||||
} else {
|
||||
if (typeof target === 'string') {
|
||||
let stat = fs.stat(target)
|
||||
var stat = fs.stat(target)
|
||||
if (stat.isFile()) {
|
||||
let size = stat.size
|
||||
if (start !== void 0) {
|
||||
if (end === void 0) {
|
||||
size -= start
|
||||
} else {
|
||||
size = end - start
|
||||
}
|
||||
}
|
||||
this.length = size
|
||||
return fs.origin
|
||||
.createReadStream(target, { start, end })
|
||||
.pipe(this.#res)
|
||||
this.set('Content-Length', stat.size)
|
||||
fs.origin.createReadStream(target).pipe(this.origin.res)
|
||||
return
|
||||
}
|
||||
}
|
||||
data = Buffer.from(target + '')
|
||||
}
|
||||
|
||||
if (start !== void 0) {
|
||||
data = data.slice(start, end)
|
||||
}
|
||||
|
||||
this.length = data.length
|
||||
this.body = data
|
||||
}
|
||||
|
||||
load(file, type, expires = 24 * 3600) {
|
||||
let stat = fs.stat(file)
|
||||
if (stat.isFile()) {
|
||||
let size = stat.size
|
||||
|
||||
let _type = type || file.split('.').pop() || 'stream'
|
||||
|
||||
this.expires = expires
|
||||
this.type = _type
|
||||
this.length = stat.size
|
||||
return fs.origin.createReadStream(file).pipe(this.#res)
|
||||
} else {
|
||||
this.status = 404
|
||||
this.body = null
|
||||
}
|
||||
this.set('Content-Length', data.length)
|
||||
this.end(data)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,55 +112,93 @@ export default class Response {
|
|||
* @param {Num} code [返回码]
|
||||
* @param {Str} msg [提示信息]
|
||||
* @param {Str/Obj} data [额外数据]
|
||||
* @param {Str} callback [回调函数名]
|
||||
*/
|
||||
send(code = 200, msg = '', data) {
|
||||
let output
|
||||
send(code = 200, msg = 'success', data = null, callback = null) {
|
||||
var output
|
||||
|
||||
if (this.#ended) {
|
||||
if (this.rendered) {
|
||||
return
|
||||
}
|
||||
|
||||
if (msg && typeof msg === 'object') {
|
||||
data = msg
|
||||
if (typeof code !== 'number') {
|
||||
if (typeof code === 'object') {
|
||||
data = code
|
||||
code = 200
|
||||
msg = STATUS_TEXT[code]
|
||||
} else {
|
||||
msg = msg || STATUS_TEXT[code]
|
||||
msg = code + ''
|
||||
code = 400
|
||||
}
|
||||
} else if (typeof msg === 'object') {
|
||||
data = msg
|
||||
code = code || 200
|
||||
msg = STATUS_TEXT[code] || 'success'
|
||||
}
|
||||
|
||||
output = JSON.stringify({ code, msg, data })
|
||||
output = { code, msg, data }
|
||||
output = JSON.stringify(output)
|
||||
|
||||
this.type = 'json'
|
||||
this.length = Buffer.byteLength(output)
|
||||
if (callback) {
|
||||
callback = callback.replace(/[^\w\-\.]/g, '')
|
||||
output = callback + '(' + output + ')'
|
||||
}
|
||||
|
||||
this.set('Content-Type', 'application/json')
|
||||
this.set('Content-Length', Buffer.byteLength(output))
|
||||
|
||||
// 只设置200以上的值
|
||||
if (code && code >= 200 && code <= 599) {
|
||||
this.status = code
|
||||
if (code && code > 200) {
|
||||
this.status(code)
|
||||
}
|
||||
|
||||
this.body = output
|
||||
this.end(output)
|
||||
}
|
||||
|
||||
end(buf) {
|
||||
var code = 200
|
||||
if (this.rendered) {
|
||||
return this
|
||||
}
|
||||
if (this.statusCode) {
|
||||
code = this.statusCode
|
||||
delete this.statusCode
|
||||
}
|
||||
this.rendered = true
|
||||
this.origin.res.writeHead(code, STATUS_TEXT[code])
|
||||
this.origin.res.end(buf || '')
|
||||
}
|
||||
|
||||
/**
|
||||
* [get 读取已写入的头信息]
|
||||
*/
|
||||
get(key) {
|
||||
return this.#res.getHeader(key)
|
||||
return this.origin.res.getHeader(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* [set 设置头信息]
|
||||
*/
|
||||
set(key, val) {
|
||||
if (this.#ended) {
|
||||
if (this.rendered) {
|
||||
return this
|
||||
}
|
||||
let value = Array.isArray(val) ? val.map(String) : String(val)
|
||||
this.#res.setHeader(key, value)
|
||||
return this
|
||||
if (arguments.length === 2) {
|
||||
var value = Array.isArray(val) ? val.map(String) : String(val)
|
||||
|
||||
if (
|
||||
key.toLowerCase() === 'content-type' &&
|
||||
typeof value === 'string' &&
|
||||
value.indexOf('charset') < 0
|
||||
) {
|
||||
value += '; charset=utf-8'
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
this.#res.removeHeader(key)
|
||||
this.origin.res.setHeader(key, value)
|
||||
} else {
|
||||
for (let i in key) {
|
||||
this.set(i, key[i])
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -264,18 +208,26 @@ export default class Response {
|
|||
* @param {String} val [description]
|
||||
*/
|
||||
append(key, val) {
|
||||
if (this.#ended) {
|
||||
if (this.rendered) {
|
||||
return
|
||||
}
|
||||
let prev = this.get(key) || []
|
||||
var prev = this.get(key)
|
||||
var value
|
||||
|
||||
if (!Array.isArray(prev)) {
|
||||
prev = [prev]
|
||||
if (Array.isArray(val)) {
|
||||
value = val
|
||||
} else {
|
||||
value = [val]
|
||||
}
|
||||
|
||||
prev = prev.concat(val)
|
||||
|
||||
return this.set(key, prev)
|
||||
if (prev) {
|
||||
if (Array.isArray(prev)) {
|
||||
value = prev.concat(val)
|
||||
} else {
|
||||
value = [prev].concat(val)
|
||||
}
|
||||
}
|
||||
return this.set(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,7 +238,7 @@ export default class Response {
|
|||
*/
|
||||
cookie(key, val, opts = {}) {
|
||||
//读取之前已经写过的cookie缓存
|
||||
let cache = this.get('set-cookie')
|
||||
var cache = this.get('set-cookie')
|
||||
if (cache) {
|
||||
if (!Array.isArray(cache)) {
|
||||
cache = [cache]
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
* @date 2020/09/20 15:08:50
|
||||
*/
|
||||
|
||||
const KEY_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/
|
||||
// const SPLIT_REGEXP = /; */
|
||||
const encode = encodeURIComponent
|
||||
// const decode = decodeURIComponent
|
||||
var KEY_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/
|
||||
// var SPLIT_REGEXP = /; */
|
||||
var encode = encodeURIComponent
|
||||
// var decode = decodeURIComponent
|
||||
|
||||
/**
|
||||
* [serialize 序列化对象]
|
||||
*/
|
||||
export function serialize(key, val, opts) {
|
||||
let pairs = []
|
||||
var pairs = []
|
||||
if (!KEY_REGEXP.test(key)) {
|
||||
return ''
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ export function serialize(key, val, opts) {
|
|||
if (opts.hasOwnProperty('expires') && opts.expires) {
|
||||
// pairs.push('Expires=' + opts.expires.toUTCString())
|
||||
// 有效期, 已不建议使用,改用 max-age
|
||||
if (opts.expires instanceof Date) {
|
||||
if (Date.isDate(opts.expires)) {
|
||||
opts.maxAge = ~~(opts.expires.getTime() / 1000)
|
||||
} else {
|
||||
opts.maxAge = +opts.expires
|
||||
|
|
|
@ -2,7 +2,6 @@ export default {
|
|||
'100': 'Continue',
|
||||
'101': 'Switching Protocols',
|
||||
'102': 'Processing',
|
||||
'103': 'Early Hints',
|
||||
'200': 'OK',
|
||||
'201': 'Created',
|
||||
'202': 'Accepted',
|
||||
|
@ -12,7 +11,6 @@ export default {
|
|||
'206': 'Partial Conten',
|
||||
'207': 'Multi-Status',
|
||||
'208': 'Already Reported',
|
||||
'218': 'This is fine',
|
||||
'226': 'IM Used',
|
||||
'300': 'Multiple Choices',
|
||||
'301': 'Moved Permanently',
|
||||
|
@ -42,32 +40,20 @@ export default {
|
|||
'416': 'Requested Range Not Satisfiable',
|
||||
'417': 'Expectation Failed',
|
||||
'418': "I'm a teapot",
|
||||
'419': 'Page Expired',
|
||||
'420': 'Enhance Your Caim',
|
||||
'421': 'Misdirected Request',
|
||||
'422': 'Unprocessable Entity',
|
||||
'423': 'Locked',
|
||||
'424': 'Failed Dependency',
|
||||
'425': 'Too Early',
|
||||
'425': 'Unordered Collection',
|
||||
'426': 'Upgrade Required',
|
||||
'428': 'Precondition Required',
|
||||
'429': 'Too Many Requests',
|
||||
'430': 'Would Block',
|
||||
'431': 'Request Header Fields Too Large',
|
||||
'440': 'Login Time-Out',
|
||||
'444': 'No Response',
|
||||
'449': 'Retry With',
|
||||
'450': 'Blocked by Windows Parental Controls',
|
||||
'451': 'Unavailable For Legal Reasons',
|
||||
'460': 'Client Closed Connection Prematurely',
|
||||
'463': 'Too Many Forwarded IP Addresses',
|
||||
'464': 'Incompatible Protocol',
|
||||
'494': 'Request Header Too Large',
|
||||
'495': 'SSL Certificate Error',
|
||||
'496': 'SSL Certificate Required',
|
||||
'497': 'HTTP Request Sent to HTTPS Port',
|
||||
'498': 'Invalid Token',
|
||||
'499': 'Token Required or Client Closed Request',
|
||||
'500': 'Internal Server Error',
|
||||
'501': 'Not Implemented',
|
||||
'502': 'Bad Gateway',
|
||||
|
@ -77,20 +63,6 @@ export default {
|
|||
'506': 'Variant Also Negotiates',
|
||||
'507': 'Insufficient Storage',
|
||||
'508': 'Loop Detected',
|
||||
'509': 'Bandwidth Limit Exceeded',
|
||||
'510': 'Not Extended',
|
||||
'511': 'Network Authentication Required',
|
||||
'520': 'Web Server Is Returning an Unknown Error',
|
||||
'521': 'Web Server Is Down',
|
||||
'522': 'Connection Timed Out',
|
||||
'523': 'Origin Is Unreachable',
|
||||
'524': 'A Timeout Occurred',
|
||||
'525': 'SSL Handshake Failed',
|
||||
'526': 'Invalid SSL Certificate',
|
||||
'527': 'Railgun Listener to Origin',
|
||||
'529': 'The Service Is Overloaded',
|
||||
'530': 'Site Frozen',
|
||||
'561': 'Unauthorized',
|
||||
'598': 'Network Read Timeout Error',
|
||||
'599': 'Network Connect Timeout Error',
|
||||
'511': 'Network Authentication Required'
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
//
|
||||
|
||||
export const CHARSET_TYPES = {
|
||||
html: 1,
|
||||
txt: 1,
|
||||
css: 1,
|
||||
scss: 1,
|
||||
xml: 1,
|
||||
js: 1,
|
||||
json: 1,
|
||||
webmanifest: 1
|
||||
}
|
||||
|
||||
export const MIME_TYPES = {
|
||||
html: 'text/html',
|
||||
xml: 'text/xml',
|
||||
txt: 'text/plain',
|
||||
css: 'text/css',
|
||||
js: 'application/javascript',
|
||||
json: 'application/json',
|
||||
webmanifest: 'application/json',
|
||||
wast: 'application/wast',
|
||||
wasm: 'application/wasm',
|
||||
|
||||
gif: 'image/gif',
|
||||
jpg: 'image/jpeg',
|
||||
webp: 'image/webp',
|
||||
tiff: 'image/tiff',
|
||||
png: 'image/png',
|
||||
apng: 'image/apng',
|
||||
svg: 'image/svg+xml',
|
||||
ico: 'image/x-icon',
|
||||
bmp: 'image/x-ms-bmp',
|
||||
|
||||
mid: 'audio/midi',
|
||||
midi: 'audio/x-midi',
|
||||
mp3: 'audio/mpeg',
|
||||
ogg: 'audio/ogg',
|
||||
m4a: 'audio/x-m4a',
|
||||
mp4: 'video/mp4',
|
||||
webm: 'video/webm',
|
||||
|
||||
ttf: 'font/font-ttf',
|
||||
woff: 'font/font-woff',
|
||||
woff2: 'font/font-woff2',
|
||||
|
||||
zip: 'application/zip',
|
||||
'7zip': 'application/zip',
|
||||
rar: 'application/rar',
|
||||
gz: 'application/x-gzip',
|
||||
tar: 'application/x-tar',
|
||||
tgz: 'application/x-tar',
|
||||
|
||||
pdf: 'application/pdf',
|
||||
psd: 'application/x-photoshop',
|
||||
|
||||
doc: 'application/msword',
|
||||
xls: 'application/vnd.ms-excel',
|
||||
ppt: 'application/vnd.ms-powerpoint',
|
||||
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
|
||||
stream: 'application/octet-stream'
|
||||
}
|
||||
|
||||
MIME_TYPES.vue = MIME_TYPES.js
|
||||
MIME_TYPES.scss = MIME_TYPES.css
|
||||
MIME_TYPES.htm = MIME_TYPES.html
|
||||
MIME_TYPES.jpeg = MIME_TYPES.jpg
|
||||
MIME_TYPES.tif = MIME_TYPES.tiff
|
12
package.json
12
package.json
|
@ -1,18 +1,14 @@
|
|||
{
|
||||
"name": "@gm5/response",
|
||||
"version": "2.1.1",
|
||||
"version": "1.3.1",
|
||||
"type": "module",
|
||||
"description": "对Http的response进一步封装, 提供常用的API",
|
||||
"main": "index.js",
|
||||
"author": "yutent",
|
||||
"keywords": [
|
||||
"fivejs",
|
||||
"response",
|
||||
"http"
|
||||
],
|
||||
"keywords": ["fivejs", "response", "http"],
|
||||
"dependencies": {
|
||||
"iofs": "^1.5.3"
|
||||
"iofs": "^1.5.0"
|
||||
},
|
||||
"repository": "https://git.wkit.fun/gm5/response.git",
|
||||
"repository": "https://github.com/bytedo/gmf.response.git",
|
||||
"license": "MIT"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue