返回 XML 作为 Loopback Remote Method 的响应
Returning XML in response from Loopback Remote Method
我正在使用环回连接器 REST (1.9.0) 并且有一个远程方法 returns XML:
Foo.remoteMethod
(
"getXml",
{
accepts: [
{arg: 'id', type: 'string', required: true }
],
http: {path: '/:id/content', "verb": 'get'},
returns: {"type": "string", root:true},
rest: {"after": setContentType("text/xml") }
}
)
响应总是 return 一个转义的 JSON 字符串:
"<foo xmlns=\"bar\"/>"
而不是
<foo xmlns="bar"/>
请注意,响应确实将 content-type 设置为 text/xml。
如果我将接受:header 设置为 "text/xml",我总是会收到 "Not Acceptable" 作为响应。
如果我设置
"rest": {
"normalizeHttpPath": false,
"xml": true
}
在 config.json 中,然后我得到一个 500 错误:
SyntaxError: Unexpected token <
我认为 "xml: true" 属性 只是导致响应解析器尝试将 JSON 转换为 XML。
如何在不解析的情况下将响应中的 return 环回 XML?是我将 return 类型设置为 "string" 的问题吗?如果是这样,Loopback 将识别为 XML 的类型是什么?
您需要在回复 object 中设置为 XML(稍后会详细介绍)。首先,将 return 类型设置为 'object' 如下所示:
Foo.remoteMethod
(
"getXml",
{
accepts: [
{arg: 'id', type: 'string', required: true }
],
http: {path: '/:id/content', "verb": 'get'},
returns: {"type": "object", root:true},
rest: {"after": setContentType("text/xml") }
}
)
接下来,您需要 return 一个 JSON object 和 XML 作为唯一的 属性。 toXML 应该是一个函数,它 return 是 XML 的字符串表示形式。如果将接受 header 设置为 "text/xml",则响应应为 XML。见下文:
Foo.getXml = function(cb) {
cb(null, {
toXML: function() {
return '<something></something>';
}
});
};
您仍然需要在 config.json 中启用 XML,因为默认情况下它是禁用的:
"remoting": {
"rest": {
"normalizeHttpPath": false,
"xml": true
}
}
请参阅 https://github.com/strongloop/strong-remoting/blob/4b74a612d3c969d15e3dcc4a6d978aa0514cd9e6/lib/http-context.js#L393 以了解有关其内部工作原理的更多信息。
我最近 运行 尝试在 Loopback 3.x 中为 Twilio 语音呼叫创建动态响应。在 model.remoteMethod 调用中,显式指定 return 类型和内容类型,如下所示:
model.remoteMethod(
"voiceResponse", {
accepts: [{
arg: 'envelopeId',
type: 'number',
required: true
}],
http: {
path: '/speak/:envelopeId',
"verb": 'post'
},
returns: [{
arg: 'body',
type: 'file',
root: true
}, {
arg: 'Content-Type',
type: 'string',
http: {
target: 'header'
}
}],
}
)
通过回调函数让您的方法 return 同时具有 xml 和内容类型。请注意,回调中的第一个参数是 return 如果存在错误:
model.voiceResponse = function(messageEnvelopeId, callback) {
app.models.messageEnvelope.findById(messageEnvelopeId, {
include: ['messages']
}).then(function(res) {
let voiceResponse = new VoiceResponse();
voiceResponse.say({
voice: 'woman',
language: 'en'
},
"This is a notification alert from your grow system. " + res.toJSON().messages.message
)
callback(null,
voiceResponse.toString(), // returns xml document as a string
'text/xml'
);
});
}
我正在使用环回连接器 REST (1.9.0) 并且有一个远程方法 returns XML:
Foo.remoteMethod
(
"getXml",
{
accepts: [
{arg: 'id', type: 'string', required: true }
],
http: {path: '/:id/content', "verb": 'get'},
returns: {"type": "string", root:true},
rest: {"after": setContentType("text/xml") }
}
)
响应总是 return 一个转义的 JSON 字符串:
"<foo xmlns=\"bar\"/>"
而不是
<foo xmlns="bar"/>
请注意,响应确实将 content-type 设置为 text/xml。
如果我将接受:header 设置为 "text/xml",我总是会收到 "Not Acceptable" 作为响应。
如果我设置
"rest": {
"normalizeHttpPath": false,
"xml": true
}
在 config.json 中,然后我得到一个 500 错误:
SyntaxError: Unexpected token <
我认为 "xml: true" 属性 只是导致响应解析器尝试将 JSON 转换为 XML。
如何在不解析的情况下将响应中的 return 环回 XML?是我将 return 类型设置为 "string" 的问题吗?如果是这样,Loopback 将识别为 XML 的类型是什么?
您需要在回复 object 中设置为 XML(稍后会详细介绍)。首先,将 return 类型设置为 'object' 如下所示:
Foo.remoteMethod
(
"getXml",
{
accepts: [
{arg: 'id', type: 'string', required: true }
],
http: {path: '/:id/content', "verb": 'get'},
returns: {"type": "object", root:true},
rest: {"after": setContentType("text/xml") }
}
)
接下来,您需要 return 一个 JSON object 和 XML 作为唯一的 属性。 toXML 应该是一个函数,它 return 是 XML 的字符串表示形式。如果将接受 header 设置为 "text/xml",则响应应为 XML。见下文:
Foo.getXml = function(cb) {
cb(null, {
toXML: function() {
return '<something></something>';
}
});
};
您仍然需要在 config.json 中启用 XML,因为默认情况下它是禁用的:
"remoting": {
"rest": {
"normalizeHttpPath": false,
"xml": true
}
}
请参阅 https://github.com/strongloop/strong-remoting/blob/4b74a612d3c969d15e3dcc4a6d978aa0514cd9e6/lib/http-context.js#L393 以了解有关其内部工作原理的更多信息。
我最近 运行 尝试在 Loopback 3.x 中为 Twilio 语音呼叫创建动态响应。在 model.remoteMethod 调用中,显式指定 return 类型和内容类型,如下所示:
model.remoteMethod(
"voiceResponse", {
accepts: [{
arg: 'envelopeId',
type: 'number',
required: true
}],
http: {
path: '/speak/:envelopeId',
"verb": 'post'
},
returns: [{
arg: 'body',
type: 'file',
root: true
}, {
arg: 'Content-Type',
type: 'string',
http: {
target: 'header'
}
}],
}
)
通过回调函数让您的方法 return 同时具有 xml 和内容类型。请注意,回调中的第一个参数是 return 如果存在错误:
model.voiceResponse = function(messageEnvelopeId, callback) {
app.models.messageEnvelope.findById(messageEnvelopeId, {
include: ['messages']
}).then(function(res) {
let voiceResponse = new VoiceResponse();
voiceResponse.say({
voice: 'woman',
language: 'en'
},
"This is a notification alert from your grow system. " + res.toJSON().messages.message
)
callback(null,
voiceResponse.toString(), // returns xml document as a string
'text/xml'
);
});
}