Sni*_*per 18 azure azure-storage node.js azure-mobile-services azure-storage-files
我们正在尝试创建一个Web服务,使用node.js服务将文件上载到Azure文件存储.
下面是node.js服务器代码.
exports.post = function(request, response){
var shareName = request.headers.sharename;
var dirPath = request.headers.directorypath;
var fileName = request.headers.filename;
var body;
var length;
request.on("data", function(chunk){
body += chunk;
console.log("Get data");
});
request.on("end", function(){
try{
console.log("end");
var data = body;
length = data.length;
console.log(body); // This giving the result as undefined
console.log(length);
fileService.createFileFromStream(shareName, dirPath, fileName, body, length, function(error, result, resp) {
if (!error) {
// file uploaded
response.send(statusCodes.OK, "File Uploaded");
}else{
response.send(statusCodes.OK, "Error!");
}
});
}catch (er) {
response.statusCode = 400;
return res.end('error: ' + er.message);
}
});
}
Run Code Online (Sandbox Code Playgroud)
以下是我们上传文件的客户端.
private static void sendPOST() throws IOException {
URL obj = new URL("https://crowdtest-fileservice.azure-mobile.net/api/files_stage/");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("sharename", "newamactashare");
con.setRequestProperty("directorypath", "MaheshApp/TestLibrary/");
con.setRequestProperty("filename", "temp.txt");
Path path = Paths.get("C:/Users/uma.maheshwaran/Desktop/Temp.txt");
byte[] data = Files.readAllBytes(path);
// For POST only - START
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write(data);
os.flush();
os.close();
// For POST only - END
int responseCode = con.getResponseCode();
System.out.println("POST Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
System.out.println(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
} else {
BufferedReader br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
String line = "";
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("POST request not worked");
}
}
Run Code Online (Sandbox Code Playgroud)
它显示错误
请求'POST/api/files_stage /'已超时.这可能是由于脚本无法写入响应,或者无法及时从异步调用返回而导致的.
更新:
我也试过下面的代码.
var body = new Object();
body = request.body;
var length = body.length;
console.log(request.body);
console.log(body);
console.log(length);
try {
fileService.createFileFromStream(shareName, dirPath, fileName, body, length, function(error, result, resp) {
if (!error) {
// file uploaded
response.send(statusCodes.OK, "File Uploaded");
}else{
response.send(statusCodes.OK, "Error!");
}
});
} catch (ex) {
response.send(500, { error: ex.message });
}
Run Code Online (Sandbox Code Playgroud)
但面对这个问题
{"error":"函数createFileFromStream的参数流应该是一个对象"}
我是node.js的新手.请帮我解决这个问题.
这里有几个问题.让我们逐一介绍它们.
1.在Java客户端中,您不能只将二进制数据转储到Azure移动服务连接中.
这样做的原因是Azure移动服务有两个主体解析器,无论如何都可以确保为您解析请求主体.因此,虽然您可以通过指定不常见的内容类型来遍历Express正文解析器,但您仍然会通过天真地假设它是UTF-8字符串来点击Azure主体解析器,这会破坏您的数据流.
因此,唯一的选择是通过指定无法处理的内容类型跳过Express解析器,然后通过使用Base64编码对二进制数据进行编码来与Azure解析器一起播放.
所以,在Java客户端替换
Path path = Paths.get("C:/Users/uma.maheshwaran/Desktop/Temp.txt");
byte[] data = Files.readAllBytes(path);
Run Code Online (Sandbox Code Playgroud)
同
con.setRequestProperty("content-type", "binary");
Path path = Paths.get("C:/Users/uma.maheshwaran/Desktop/Temp.txt");
byte[] data = Files.readAllBytes(path);
data = Base64.getEncoder().encode(data);
Run Code Online (Sandbox Code Playgroud)
如果您不在Java 8上,请将java.util.Base64编码器替换为您有权访问的任何其他Base64编码器.
2. createFileFromStream
您尝试使用的Azure存储api功能需要一个流.
同时,手动解析请求主体时可以获得的最佳结果是字节数组.不幸的是,Azure移动服务使用NodeJS版本0.8,这意味着没有简单的方法来构建来自字节数组的可读流,并且您必须组装适合Azure存储API的自己的流.一些胶带和stream@0.0.1应该没问题.
var base64 = require('base64-js'),
Stream = require('stream'),
fileService = require('azure-storage')
.createFileService('yourStorageAccount', 'yourStoragePassword');
exports.post = function (req, res) {
var data = base64.toByteArray(req.body),
buffer = new Buffer(data),
stream = new Stream();
stream['_ended'] = false;
stream['pause'] = function() {
stream['_paused'] = true;
};
stream['resume'] = function() {
if(stream['_paused'] && !stream['_ended']) {
stream.emit('data', buffer);
stream['_ended'] = true;
stream.emit('end');
}
};
try {
fileService.createFileFromStream(req.headers.sharename, req.headers.directorypath,
req.headers.filename, stream, data.length, function (error, result, resp) {
res.statusCode = error ? 500 : 200;
res.end();
}
);
} catch (e) {
res.statusCode = 500;
res.end();
}
};
Run Code Online (Sandbox Code Playgroud)
这些是此示例所需的依赖项.
"dependencies": {
"azure-storage": "^0.7.0",
"base64-js": "^0.0.8",
"stream": "0.0.1"
}
Run Code Online (Sandbox Code Playgroud)
如果在服务的package.json中指定它们不起作用,您可以随时转到此链接并通过控制台手动安装它们.
cd site\wwwroot
npm install azure-storage
npm install base64-js
npm install stream@0.0.1
Run Code Online (Sandbox Code Playgroud)
3.要增加1Mb的默认上载限制,请为您的服务指定MS_MaxRequestBodySizeKB.
请记住,因为您将数据作为Base64编码传输,您必须考虑到这种开销.因此,要支持上传大小为20Mb的文件,您必须设置MS_MaxRequestBodySizeKB
为大约20*1024*4/3 = 27307.
归档时间: |
|
查看次数: |
6016 次 |
最近记录: |