怎么让egg接受text/xml 的参数呢
bodyparser 可以支持 text,xml 解析需要自行处理
const errorModule = require("../config/error.modules");
const xmlparser = require('xml2json');
// 是否开启token验证
const AUTH_CHECK = false;
xmlToJson = str => {
return new Promise((resolve, reject) => {
resolve(JSON.parse(xmlparser.toJson(str)).xml);
})
}
/**
----入参----${JSON.stringify(this.request.body)}); //token鉴权
if(AUTH_CHECK){
try {
let authorization = JSON.parse(this.header.authorization);
let uid = authorization.id;
let redisKey = 'token_' + uid;
// redis解析hashMap的值
let tokenInfo = yield this.app.redis.hget(redisKey, uid);
if(!tokenInfo){
this.response.body = errorModule.TOKEN_ERR;
this.logger.info(`----出参----${JSON.stringify(this.response.body)}`);
this.status = 403;
return;
}
} catch (e) {
this.logger.error(e.message);
this.response.body = errorModule.TOKEN_ERR;
this.logger.info(`----出参----${JSON.stringify(this.response.body)}`);
this.status = 403;
return;
}
}
//入参参数校验
try{
let self = this;
//把xml转成json
if(this.request.header["content-type"] === 'text/xml'){
let promise = new Promise(function (resolve, reject) {
let buf = ''
self.req.on('data', (chunk) => {
buf += chunk
})
self.req.on('end', () => {
xmlToJson(buf)
.then(resolve)
.catch(reject)
})
})
promise.then((result) => {
self.request.body = result;
//拦截request请求
this.logger.info(`----入参text/xml----${JSON.stringify(self.request.body)}`);
})
.catch((e) => {
self.response.body = errorModule.JSON_PARSE_ERR;
self.status = 400;
return;
})
} else {
//入参处理
let reqJson = this.request.body.json;
//入参重新赋值
this.request.body = JSON.parse(reqJson);
}
} catch (e) {
this.response.body = errorModule.JSON_PARSE_ERR;
this.logger.info(`----出参----${JSON.stringify(this.response.body)}`);
return;
}
//返回控制权给控制器
yield next;
//拦截response请求
if(this.response.body){
this.logger.info(`----出参----${JSON.stringify(this.response.body)}`);
}
};
};
用了koa-bodyparser 还是拿不到body的值
创建一个中间件: interceptor.js
const getRawBody = require("raw-body");
const xmlparser = require('xml2json');
/**
* 接口req res拦截器
*/
module.exports = options => {
return function* interceptor(next) {
//拦截request请求
this.logger.info(`----入参----${JSON.stringify(this.request.body)}`);
//入参参数校验
try{
//把xml转成json
if(this.request.header["content-type"] === 'text/xml'){
let buff = yield getRawBody(this.request.req);
let resultjson = JSON.parse(xmlparser.toJson(buff)).xml;
this.request.body = resultjson;
} else {
//入参处理
let reqJson = this.request.body.json;
//入参重新赋值
this.request.body = JSON.parse(reqJson);
}
} catch (e) {
this.response.body = errorModule.JSON_PARSE_ERR;
this.logger.info(`----出参----${JSON.stringify(this.response.body)}`);
return;
}
//返回控制权给控制器
yield next;
//拦截response请求
if(this.response.body){
this.logger.info(`----出参----${JSON.stringify(this.response.body)}`);
}
};
};
config.middleware = ['interceptor'];
这样可以了,上面那个不用。会拦截所有xml请求,转成json。
可行的
@cwc845982120
可以用co-wechat-body也可行的,会简单很多。
@longxianlin 你好, errorModule没有获取到, 可以提供一下吗?
更新一波,方便后来人。另,enableTypes、extendTypes等参数ts定义没加上。我似乎可以。。。
const bodyParserConfig: any = {
enable: true,
encoding: 'utf8',
formLimit: '100kb',
jsonLimit: '100kb',
strict: true,
// @see https://github.com/hapijs/qs/blob/master/lib/parse.js#L8 for more options
queryString: {
arrayLimit: 100,
depth: 5,
parameterLimit: 1000,
},
enableTypes: ['json', 'form', 'text'],
extendTypes: {
text: ['text/xml', 'application/xml'],
},
};
// 覆盖egg自带的配置
config.bodyParser = bodyParserConfig;
@wangtao0101 送上后来人的感觉
@wangtao0101 PR
@wangtao0101 可用,感谢~
@wangtao0101 const bodyParserConfig: any = { => const bodyParserConfig = {
太感谢了,good !
创建一个中间件: interceptor.js
const getRawBody = require("raw-body"); const xmlparser = require('xml2json'); /** * 接口req res拦截器 */ module.exports = options => { return function* interceptor(next) { //拦截request请求 this.logger.info(`----入参----${JSON.stringify(this.request.body)}`); //入参参数校验 try{ //把xml转成json if(this.request.header["content-type"] === 'text/xml'){ let buff = yield getRawBody(this.request.req); let resultjson = JSON.parse(xmlparser.toJson(buff)).xml; this.request.body = resultjson; } else { //入参处理 let reqJson = this.request.body.json; //入参重新赋值 this.request.body = JSON.parse(reqJson); } } catch (e) { this.response.body = errorModule.JSON_PARSE_ERR; this.logger.info(`----出参----${JSON.stringify(this.response.body)}`); return; } //返回控制权给控制器 yield next; //拦截response请求 if(this.response.body){ this.logger.info(`----出参----${JSON.stringify(this.response.body)}`); } }; };config.middleware = ['interceptor'];这样可以了,上面那个不用。会拦截所有xml请求,转成json。
这个在 egg 2.26.0 版本下貌似有问题
看楼上。。。 https://github.com/eggjs/egg/issues/974#issuecomment-388561452 不需要写中间件 getRawBody。
@atian25 这个测试成功,是在 body 里面返回个 xml 字符串。但是默认没有转换为 object ,这里需要在 controller 里面自己处理吗?谢谢
肯定啦,就是一个 plaintext,自己引入 xml 库去解析
再问下,如果 Content-Type 为空的情况下,如何保证能把内容获取到呢?
POST /hook/testxml HTTP/1.1
Cache-Control: no-cache
Host: 127.0.0.1:7001
Content-Length: 24
xxxxxxxx
========
我设置成这样,返回的body也为空
extendTypes: {
text: ['text/xml', 'application/xml','text/html','']
},
不应该为空。
不用那么麻烦,改下配制就可以
https://blog.csdn.net/ximenxiafeng/article/details/110294754
Most helpful comment
更新一波,方便后来人。另,enableTypes、extendTypes等参数ts定义没加上。我似乎可以。。。