Egg: 怎么让egg接受text/xml 的参数呢

Created on 31 May 2017  ·  21Comments  ·  Source: eggjs/egg

怎么让egg接受text/xml 的参数呢

Most helpful comment

更新一波,方便后来人。另,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;

All 21 comments

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);
})
}
/**

  • 接口req res拦截器
    /
    module.exports = options => {
    return function
    interceptor(next) {
    //拦截request请求
    this.logger.info(----入参----${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

Was this page helpful?
0 / 5 - 0 ratings