Compare commits
No commits in common. "master" and "v2" have entirely different histories.
182
Readme.md
182
Readme.md
|
@ -1,5 +1,4 @@
|
||||||
![downloads](https://img.shields.io/npm/dt/@gm5/response.svg)
|
![module info](https://nodei.co/npm/@gm5/response.png?downloads=true&downloadRank=true&stars=true)
|
||||||
![version](https://img.shields.io/npm/v/@gm5/response.svg)
|
|
||||||
|
|
||||||
# @gm5/response
|
# @gm5/response
|
||||||
|
|
||||||
|
@ -21,8 +20,181 @@ http
|
||||||
.createServer((req, res) => {
|
.createServer((req, res) => {
|
||||||
let response = new Response(req, res)
|
let response = new Response(req, res)
|
||||||
|
|
||||||
response.type = 'html'
|
// it eq. argument res
|
||||||
response.body = '<h1>hello world</h1>'
|
console.log(response.res)
|
||||||
|
|
||||||
|
response.set('content-type', 'text/html; charset=utf-8')
|
||||||
|
response.end('hello world')
|
||||||
})
|
})
|
||||||
.listen(3000)
|
.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。
|
38
index.js
38
index.js
|
@ -56,15 +56,6 @@ export default class Response {
|
||||||
this.#res.end(buf)
|
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [error http 错误显示]
|
* [error http 错误显示]
|
||||||
* @param {Number} code [http错误码]
|
* @param {Number} code [http错误码]
|
||||||
|
@ -117,13 +108,13 @@ export default class Response {
|
||||||
data += ''
|
data += ''
|
||||||
data = data || STATUS_TEXT[this.status]
|
data = data || STATUS_TEXT[this.status]
|
||||||
this.type = 'html'
|
this.type = 'html'
|
||||||
this.length = Buffer.byteLength(data)
|
this.set('Content-Length', Buffer.byteLength(data))
|
||||||
|
|
||||||
this.body = data
|
this.body = data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件下载
|
// 文件下载
|
||||||
sendfile(target, filename = 'untitled', expires = 3600) {
|
sendfile(target, filename = 'untitled') {
|
||||||
if (this.#ended) {
|
if (this.#ended) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -151,8 +142,6 @@ export default class Response {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.expires = expires
|
|
||||||
|
|
||||||
if (Buffer.isBuffer(target)) {
|
if (Buffer.isBuffer(target)) {
|
||||||
data = target
|
data = target
|
||||||
} else {
|
} else {
|
||||||
|
@ -167,7 +156,7 @@ export default class Response {
|
||||||
size = end - start
|
size = end - start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.length = size
|
this.set('Content-Length', size)
|
||||||
return fs.origin
|
return fs.origin
|
||||||
.createReadStream(target, { start, end })
|
.createReadStream(target, { start, end })
|
||||||
.pipe(this.#res)
|
.pipe(this.#res)
|
||||||
|
@ -180,27 +169,10 @@ export default class Response {
|
||||||
data = data.slice(start, end)
|
data = data.slice(start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.length = data.length
|
this.set('Content-Length', data.length)
|
||||||
this.body = data
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [send json格式输出]
|
* [send json格式输出]
|
||||||
* @param {Num} code [返回码]
|
* @param {Num} code [返回码]
|
||||||
|
@ -224,7 +196,7 @@ export default class Response {
|
||||||
output = JSON.stringify({ code, msg, data })
|
output = JSON.stringify({ code, msg, data })
|
||||||
|
|
||||||
this.type = 'json'
|
this.type = 'json'
|
||||||
this.length = Buffer.byteLength(output)
|
this.set('Content-Length', Buffer.byteLength(output))
|
||||||
|
|
||||||
// 只设置200以上的值
|
// 只设置200以上的值
|
||||||
if (code && code >= 200 && code <= 599) {
|
if (code && code >= 200 && code <= 599) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ export function serialize(key, val, opts) {
|
||||||
if (opts.hasOwnProperty('expires') && opts.expires) {
|
if (opts.hasOwnProperty('expires') && opts.expires) {
|
||||||
// pairs.push('Expires=' + opts.expires.toUTCString())
|
// pairs.push('Expires=' + opts.expires.toUTCString())
|
||||||
// 有效期, 已不建议使用,改用 max-age
|
// 有效期, 已不建议使用,改用 max-age
|
||||||
if (opts.expires instanceof Date) {
|
if (Date.isDate(opts.expires)) {
|
||||||
opts.maxAge = ~~(opts.expires.getTime() / 1000)
|
opts.maxAge = ~~(opts.expires.getTime() / 1000)
|
||||||
} else {
|
} else {
|
||||||
opts.maxAge = +opts.expires
|
opts.maxAge = +opts.expires
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@gm5/response",
|
"name": "@gm5/response",
|
||||||
"version": "2.1.1",
|
"version": "2.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "对Http的response进一步封装, 提供常用的API",
|
"description": "对Http的response进一步封装, 提供常用的API",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
@ -11,8 +11,8 @@
|
||||||
"http"
|
"http"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"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"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue