Express API JSON 和 XML POST 请求
Posted
技术标签:
【中文标题】Express API JSON 和 XML POST 请求【英文标题】:Express API JSON and XML POST request 【发布时间】:2017-05-23 23:23:31 【问题描述】:我有一个快速 API,它允许 json 发布请求。但是,在我的场景中,我的 API 之一需要接受 XML 帖子正文,而不是 JSON。
所以我的快递应用程序设置得很好:
// Init App
var app = express();
// BodyParser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded(
extended: false
));
这是我的 POST api JSON 路由的示例:
router.post('/', function(req, res, next)
defaultPoll.create(req.body, function(err, post)
if (err) console.log(err)
else res.json(post);
);
);
当我传入我的 json 值时,效果很好,例如这是我的帖子请求:
"milliseconds":"600"
但现在我有一个 API,我想在其中执行 POST 请求,但我的 POST 请求需要作为 XML 发送。所以这就是我的 API 的样子:
router.post('/test', function(req, res)
var body = req
console.log(body)
);
没有什么复杂的,因为我没有得到任何回报。这就是我执行 POST 请求的方式:
<?xml version="1.0"?>
<methodCall>
<methodName>myMethod</methodName>
<params>
<param>
<value><string>hello</string></value>
</param>
</params>
</methodCall>
然而,我的身体却空空如也。知道如何解决这个问题吗?理想情况下,我想接受这个 XML 请求,然后也用我选择的 XML 进行响应。最好的方法是什么?
接受请求,转换为 JSON,写入 JSON 响应并转换回 XML 响应?
任何帮助将不胜感激!
【问题讨论】:
【参考方案1】:bodyParser 仅支持以下格式(如果您使用的是 body-parser):
JSON 正文解析器 原始正文解析器 正文解析器 URL 编码的表单正文解析器所以如果你想解析 XML 我建议你使用 express-xml-bodyparser
var xmlparser = require('express-xml-bodyparser');
app.use(xmlparser());
app.post('/test', function(req, res, next)
// req.body contains the parsed xml
);
我希望这可以帮助你朝着正确的方向前进
【讨论】:
是否可以只为一个 API 路由做到这一点?请记住,我有很多 JSON 路由,只需要一个 XML 路由 从文档中,看起来你可以同时拥有,并且 express 会看到请求的内容类型并使用正确的。 npmjs.com/package/express-xml-bodyparser 这是一个猜测 我在我的 API 中使用了这两个解析器,并且两者都有效。 express-xml-bodyparser 按 mime 类型检测内容。 @R.Gulbrandsen npm 页面显示“解析原始 xml 正文”,所以,如果我们只使用body.parser.raw( type: "application/xml" )
并将我们在正文中获得的缓冲区转换为字符串,我们不应该得到xml 字符串?
对不起,我不知道这个问题的答案。【参考方案2】:
我相信你可以使用不同的路线
appRoute1.js
const express = require('express');
const router = express.Router();
const bodyParse = require('body-parser');
const cookieParser = require('cookie-parser');
const xmlparser = require('express-xml-bodyparser');
router.use(xmlparser());
router.use(bodyParse.json());
router.use(bodyParse.urlencoded(extended:true));
router.use(cookieParser());
router.use((req, res, next)=>
if(req.header('Content-Type').endsWith("xml"))
parser.parseString(req.body, (err, data)=>
console.log('xml data',data);
next();
)
next();
);
//router.use(courseRequestInterceptor);
router.get('/test', (req,res, next)=>
console.log('Inside router test', req);
//write a sample cookie to be sent to client
res.cookie('testCookieKey', 'testCookieValue');
res.write(JSON.stringify(id:1, test:'test', null, 2));
res.end();
),
router.post('/v1/postSampleCourse',(req,res, next)=>
console.log('cookies', req.cookies);
res.cookie('appName', 'server_demo');
debugger;
//maybe add a validation like Joi validation for the input data
res.write(JSON.stringify(['record created successfully', req.headers,
req.body.id], null, 2));
res.end();
);
module.exports = router;
appRoute2.js
const express = require('express');
const router = express.Router();
//const constants = require('./../utils/constants');
const bodyParser = require('body-parser');
router.use(bodyParser.json());
router.use(bodyParser.urlencoded(extended:true));
module.exports = router;
router.get('/addHeaders', (req, res, next)=>
req.headers['testHeader']='testHeaderValue';
//req.accepts() gets the Accept content negotiation of the incoming request, exaple if its xml or json, or ecmascript
// or stream
//req.header() requires a name of the header to see
console.log(req);
console.log('request headers', req.header('origin'));
res.header('testHeaderResponseKey', 'testHeaderResponseValue');
//
res.write(JSON.stringify(id:1));
//u can either do res.end() which will end the response and generate the result
// or pipe the response and call next() which will also end the result
req.pipe(res);
next();
)
Exec.js
const process = require('process');
const _ = require('lodash');
const util =require('util');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
//Extract arugments from command line
const argumentExtractor = require('./utils/argumentExtrator');
//make use of constants
const constants = require('./utils/constants');
//sample to make use of cors router
// const corsRouter = require('./controllers/corsRoute');
// app.use(corsRouter);
console.log('env vars', process.env);
app.use(bodyParser.json());
app.use(bodyParser.raw(type: () => true));
const corsHeaders = require('./middlewares/corsHeaders');
app.use(corsHeaders);
//additional response headers
const addition_headers = require('./middlewares/additionalReponseHeaeders');
app.use(addition_headers);
debugger;
//Routing sample1
const appRouter1 = require('./controllers/appRoute1');
app.use(constants.COURSE_ROUTE,appRouter1);
//Routing sample 2
const appRouter2 = require('./controllers/appRoute2');
app.use(constants.HEADER_ROUTE, appRouter2);
//getting the commandline properties
console.log('command line arguments');
_.each(process.argv, (data)=>
console.log('each data', data);
);
console.log('env from argument',argumentExtractor.env);
console.log('port from argument',argumentExtractor.port);
//spread opertaor example
const oldArray = ['1', 2];
const newArray = [...oldArray];
console.log(newArray);
//Rest operator- basically to handle mutiple inputs
const sampleFunc = (...params)=>
return params;
console.log(sampleFunc(3,4));
console.log(sampleFunc(3,4,5,6 ));
const port = argumentExtractor.port || 3000;
app.listen(port, () =>
console.log(`Server started on port..$port)`);
);
还有其他部分需要其他文件才能执行,但显示了路由器部分以及如何基本使用 xml 解析来进行单个路由
【讨论】:
【参考方案3】:我知道已经很晚了,但是,如果你想同时使用 xml 和 json,你可以像这样使用特定的 xml 请求,
app.post('/receive-xml', xmlparser(trim: false, explicitArray: false), function(req, res, next)
// check req.body
);
【讨论】:
【参考方案4】:body 是可读流,可以由块组成。
您可以在处理程序中执行类似的操作。
let body = "";
let response = ;
if (req.method === "POST")
req.on("data", chunk =>
body += chunk.toString();
);
req.on("end", () =>
response.message = "Success";
response.data.length = body.length;
return res.status(200).json(response);
);
【讨论】:
【参考方案5】:router.use(bodyparser.raw( type: 'application/xml' ));
XML 正文将被解析,并将采用 Buffer 格式。在路由中,您可以执行类似new Buffer(req.body.data).toString()
的操作来获取原始请求正文。
【讨论】:
以上是关于Express API JSON 和 XML POST 请求的主要内容,如果未能解决你的问题,请参考以下文章
json 使用Express JS的基本RESTful API
尝试发送 json 对象时,fetch api 如何与 express 一起使用
我正在尝试使用 json-server、Node 和 Express 在 localhost 上为我的 Angular 应用程序模拟 RESTFUL API。随之而来的 CORS 问题