Node.js 移动服务&x2B;文档数据库附件

Node.js 移动服务&x2B;文档数据库附件,node.js,azure,azure-mobile-services,azure-cosmosdb,Node.js,Azure,Azure Mobile Services,Azure Cosmosdb,这是我的堆栈: iOS和Android应用程序 文档数据库 Javascript支持的移动服务 由Javascript支持的Azure站点 我想做的是从我们的应用程序中抽象出DocumentDB的知识,因为我们正在构建白标签解决方案,我们可能需要动态扩展DocumentDB实例。通过一种抽象类型的服务,我们可以根据应用程序发送的某些数据来切分我们的docdb实例 现在,这将包括2个操作,我想创建移动服务。一个用于获取JSON数据,另一个用于获取与文档关联的附件。这就是我的麻烦所在。我有一个用

这是我的堆栈:

  • iOS和Android应用程序

  • 文档数据库

  • Javascript支持的移动服务

  • 由Javascript支持的Azure站点

我想做的是从我们的应用程序中抽象出DocumentDB的知识,因为我们正在构建白标签解决方案,我们可能需要动态扩展DocumentDB实例。通过一种抽象类型的服务,我们可以根据应用程序发送的某些数据来切分我们的docdb实例

现在,这将包括2个操作,我想创建移动服务。一个用于获取JSON数据,另一个用于获取与文档关联的附件。这就是我的麻烦所在。我有一个用NodeJS编写的直通服务,它是可部署的。我喜欢与移动服务相关联的安全模型,因此我想将我的代码调整到该模型中。问题在于将DocDB响应传输到移动服务响应。首先是移动服务的默认标题试图设置,但失败了,所以我临时覆盖了该功能。现在,移动服务永远不会响应,直到超时发生。以下是一段代码片段:

exports.get=函数(req,res){
...
//.then().fail()总是被推入fail()块,但是如果我以.then()的方式使用2函数。
readMediaAsync(mediaUrl)。然后(
//成功
职能(媒体){
//设置缓存并代理响应
media.headers[“缓存控制”]=“最大年龄=2147483647,最大过时=2147483647”;
媒体头[“pragma”]=“cache”;
for(媒体标题中的var responseHeader){
if(media.headers.hasOwnProperty(responseHeader)&&“内容位置”!=responseHeader){
res.setHeader(responseHeader,media.header[responseHeader]);
}
}
//阻止进一步修改收割台
res.setHeader=函数(字段,val){};
media.result.pipe(res,{end:true});
//media.result.on(“结束”,函数(){
//控制台日志(“附件#结束”);
//res.status(200).send();//也尝试了.end(),但没有成功
//});
},
//错误
函数(mediaError){
console.error(“documentClient.readMediaAsync fail->”+JSON.stringify(mediaError));
res.status(400).send(JSON.stringify(mediaError));
}
); ...

读取media.result.pipe(…)的行这是它挂起的地方。同样,此代码在移动服务之外工作。我一直在使用更改->提交->测试->重复循环,但没有任何运气。有人知道如何正确地将流传输到移动服务内的响应中吗?

我成功地重现了您的问题,我在请求了一段时间后获得了HTML代码e、 但是,我在LOGS选项卡中也收到了错误消息,它看起来像:

发生未处理的异常。错误:发送后无法设置头。在ServerResponse.OutgoingMessage.setHeader(http.js:679:11)在ServerResponse.res.setHeader(D:\home\site\wwwwroot\node\u modules\express\node\u modules\connect\lib\patch.js:59:22)在ServerResponse.res.set.res.header(D:\home\site\wwwroot\node\u modules\express\lib\response.js:518:10)在ServerResponse的addDefaultHeaders(D:\home\site\wwwroot\runtime\runtime\request\requesthandler.js:291:13)在ServerResponse的addDefaultHeaders(D:\home\site\wwroot\node\u modules\下划线\subline.js:692:22)在oned的.wrap[作为结束](D:\home\site\site\wwroot\wwroot\wwroot\requesthandler\no(stream.js:66:10)在EventEmitter.emit(events.js:126:20)在Object.wrapper[as oncomplete](fs.js:367:17)的afterRead(fs.js:1335:12)中

根据这个日志,我在响应中设置了管道之前的标题,这在我的测试中工作得很好

以下是我的简单代码片段:

exports.get=函数(请求、响应){
var fs=要求(“fs”);
response.setHeader=函数(字段,val){};
fs.createReadStream('files/123.txt').pipe(响应,{end:true});
};

我通过使用node documentdb sdk的非承诺版本解决了这个问题。在响应中肯定有一些东西与承诺混淆了(尽管看起来很简单)

以下是运行的代码片段:

readMedia(mediaUrl,函数(err,mediaStream){
如果(!err&&mediaStream){
mediaStream.headers[“缓存控制”]=“最大年龄=2147483647,最大过时=2147483647”;
mediaStream.headers[“pragma”]=“cache”;
for(mediaStream.headers中的var responseHeader){
if(mediaStream.headers.hasOwnProperty(responseHeader)&“内容位置”!=responseHeader){
res.setHeader(responseHeader,mediaStream.headers[responseHeader]);
}
}
res.setHeader=函数(字段,val){
};
mediaStream.pipe(res);
mediaStream.on('end',function(){
res.status(200.end();
});
}否则{
console.error(“附件(“+mediaUrl+”)catch->“+JSON.stringify(err.detail)+”;“+err.message+”;“+err.stack”);
res.status(400.send();
}
});

您的错误消息是什么?每次我们在移动服务中点击脚本并得到错误时,它都会被记录到文件中。在移动服务门户中,单击“日志”选项卡,我们可以查看错误消息。没有错误被记录。过了一段时间,它似乎超时并返回此html;。我还收到了您引用的错误,这就是为什么我添加了一行
res.setHeader=function(field,val){};
,正如您所做的那样。我将回溯一点,尝试将DocumentDB从混合中取出,并通过管道发送一个图像来查看是否有效,这可能表示流问题(至少是移动服务的问题,因为我使用SD)