From a395c87101aa70948481c15bc1ff69972b299191 Mon Sep 17 00:00:00 2001 From: yutent Date: Tue, 16 Jul 2024 17:45:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=BC=BA=E7=89=88querystring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 39 +++++++++++++++------------------------ lib/helper.js | 32 ++++++++++++++++++++++++++++++++ lib/urlencoded_parser.js | 29 +++++++++++++++++++++++------ package.json | 2 +- 4 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 lib/helper.js diff --git a/index.js b/index.js index 76ea30c..511507e 100644 --- a/index.js +++ b/index.js @@ -5,12 +5,13 @@ import 'es.shim' +import { fileURLToPath, parse } from 'node:url' +import { dirname, resolve } from 'node:path' +import fs from 'iofs' + import Parser from './lib/index.js' import { parseCookie } from './lib/cookie.js' -import fs from 'iofs' -import { fileURLToPath, parse } from 'node:url' -import QS from 'node:querystring' -import { dirname, resolve } from 'node:path' +import { querystring } from './lib/helper.js' const DEFAULT_FORM_TYPE = 'application/x-www-form-urlencoded' @@ -96,7 +97,7 @@ export default class Request { path[0] = 'index' } - if (path[0].indexOf('.') !== -1) { + if (path[0].includes('.')) { controller = path[0].slice(0, path[0].indexOf('.')) // 如果app为空(这种情况一般是url前面带了个"."造成的),则自动默认为index if (!controller || controller === '') { @@ -132,32 +133,22 @@ export default class Request { this.#body = value return } - if (~contentType.indexOf('urlencoded')) { - if ( - name.slice(0, 2) === '{"' && - (name.slice(-2) === '"}' || value.slice(-2) === '"}') - ) { - name = name.replace(/\s/g, '+') - if (value.slice(0, 1) === '=') value = '=' + value - - return Object.assign(this.#body, JSON.parse(name + value)) - } - } - - if (name.slice(-2) === '[]') { + if (name.endsWith('[]')) { name = name.slice(0, -2) if (typeof value === 'string') { value = [value] } } else if (name.slice(-1) === ']') { - let key = name.slice(name.lastIndexOf('[') + 1, -1) - name = name.slice(0, name.lastIndexOf('[')) + let idx = name.lastIndexOf('[') + let key = name.slice(idx + 1, -1) + name = name.slice(0, idx) //多解析一层对象(也仅支持到这一层) if (name.slice(-1) === ']') { - let pkey = name.slice(name.lastIndexOf('[') + 1, -1) - name = name.slice(0, name.lastIndexOf('[')) + idx = name.lastIndexOf('[') + let pkey = name.slice(idx + 1, -1) + name = name.slice(0, idx) if (!this.#body.hasOwnProperty(name)) { this.#body[name] = {} @@ -234,8 +225,8 @@ export default class Request { get query() { if (!this.#query) { - let para = parse(this.#req.url).query - this.#query = QS.parse(para) + let data = parse(this.#req.url).query + this.#query = querystring(data) } return this.#query } diff --git a/lib/helper.js b/lib/helper.js new file mode 100644 index 0000000..8cdc155 --- /dev/null +++ b/lib/helper.js @@ -0,0 +1,32 @@ +/** + * {} + * @author yutent + * @date 2024/07/16 17:01:43 + */ + +import { parse } from 'node:querystring' + +export function querystring(str) { + let query = parse(str) + for (let k of Object.keys(query)) { + let val = query[k] + + if (k.endsWith('[]')) { + let _k = k.slice(0, -2) + query[_k] = val + delete query[k] + } else if (k.endsWith(']')) { + let idx = k.lastIndexOf('[') + let _pk = k.slice(0, idx) + let _k = k.slice(idx + 1, -1) + + if (query[_pk]) { + query[_pk][_k] = val + } else { + query[_pk] = { [_k]: val } + } + delete query[k] + } + } + return query +} diff --git a/lib/urlencoded_parser.js b/lib/urlencoded_parser.js index 55020be..38d5015 100644 --- a/lib/urlencoded_parser.js +++ b/lib/urlencoded_parser.js @@ -4,23 +4,40 @@ * @date 2023/10/27 12:14:05 */ -import { parse } from 'node:querystring' import { EventEmitter } from 'node:events' +import { querystring } from './helper.js' export class UrlencodedParser extends EventEmitter { #buf = Buffer.from('') + #byteLen = 0 + + initLength(length) { + this.#byteLen = length + } write(buffer) { this.#buf = Buffer.concat([this.#buf, buffer]) } end() { - let data = this.#buf.toString() - let fields = parse(data) + if (this.#buf.length === this.#byteLen) { + let data = this.#buf.toString() + let fields = querystring(data) - this.#buf = null + this.#buf = null - this.emit('field', fields) - this.emit('end') + this.emit('field', fields) + this.emit('end') + this.#buf = null + } else { + this.emit( + 'error', + new Error( + `The uploaded data is incomplete. Expected ${ + this.#byteLen + }, Received ${this.#buf.length} .` + ) + ) + } } } diff --git a/package.json b/package.json index 324f8f0..ec82633 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gm5/request", - "version": "2.0.5", + "version": "2.0.6", "description": "对Http的Request进一步封装, 提供常用的API", "main": "index.js", "author": "yutent",