我正在使用Windows Azure做一个网站,允许用户通过网页表单提交文件,并使用POST方法发送表单。我正在使用Mac OS的最新版本,在一台2013年的Mac Book Air上。
服务器接收这个表单后,将文件流传到Blob中,并将用户重定向到一个新的带有Blob链接(公共的)的网页。这样,用户可以稍后获取他的文件。
对于小文件(大约35KB的图像,950MB的dmg文件),我的做法似乎很好用。
但是当涉及到更大的文件(大约20MB左右)时,服务器会在上传过程中出现错误(在大约1分20秒或2分40秒后,记不太清了)。客户端(Google Chrome)似乎并不知道这一点,并继续上传文件。但是当上传结束时,它会显示一个503错误。我尝试使用两个大小约为20MB的dmg文件,并得到了相同的结果(问题1)。
然后,对于一个大约57MB的DMG文件(Google Chrome安装程序)和几个大约700MB的文件(使用大约30MB/s的上传互联网连接),服务器似乎没有任何问题,客户端也没有问题。上传过程一直持续到结束,然后我得到了存储在Blob存储中的文件链接。但是当我下载它时,文件比预期的略大(对于一个57MB的文件增加了4096字节,对于一个约700MB的文件增加了大约40KB)。我尝试使用几种类型的文件:虽然有一些奇怪的东西,但足以能够回放视频,但是当我尝试挂载dmg时失败了(我猜是因为完整性检查做得不错)(问题2)。
我想知道哪些数据被添加到我的文件中。所以我创建了两个与我的大约57MB dmg文件相同大小的文件。第一个文件充满了字符0,第二个交替使用字符0和1。当我上传并下载它们时,它们的大小都不是原始大小,但它们仍然只包含000000....或010101010....。虽然真的有更多的0000...和更多的0101010....比原来的版本(但只有0和01)。
所以我去了Blob存储管理器页面,发现每个文件的大小似乎比在我的电脑上小(例如:54.33MB而不是大约57MB)。可能是因为不同的文件系统,...?
总结问题2:我上传一个大文件,在线上看起来比在我的笔记本电脑上小,然后我下载它,实际上比原来的版本要大。很奇怪,不是吗?有什么想法吗?谢谢您的帮助!
这是我的server.js文件:
服务器接收这个表单后,将文件流传到Blob中,并将用户重定向到一个新的带有Blob链接(公共的)的网页。这样,用户可以稍后获取他的文件。
对于小文件(大约35KB的图像,950MB的dmg文件),我的做法似乎很好用。
但是当涉及到更大的文件(大约20MB左右)时,服务器会在上传过程中出现错误(在大约1分20秒或2分40秒后,记不太清了)。客户端(Google Chrome)似乎并不知道这一点,并继续上传文件。但是当上传结束时,它会显示一个503错误。我尝试使用两个大小约为20MB的dmg文件,并得到了相同的结果(问题1)。
然后,对于一个大约57MB的DMG文件(Google Chrome安装程序)和几个大约700MB的文件(使用大约30MB/s的上传互联网连接),服务器似乎没有任何问题,客户端也没有问题。上传过程一直持续到结束,然后我得到了存储在Blob存储中的文件链接。但是当我下载它时,文件比预期的略大(对于一个57MB的文件增加了4096字节,对于一个约700MB的文件增加了大约40KB)。我尝试使用几种类型的文件:虽然有一些奇怪的东西,但足以能够回放视频,但是当我尝试挂载dmg时失败了(我猜是因为完整性检查做得不错)(问题2)。
我想知道哪些数据被添加到我的文件中。所以我创建了两个与我的大约57MB dmg文件相同大小的文件。第一个文件充满了字符0,第二个交替使用字符0和1。当我上传并下载它们时,它们的大小都不是原始大小,但它们仍然只包含000000....或010101010....。虽然真的有更多的0000...和更多的0101010....比原来的版本(但只有0和01)。
所以我去了Blob存储管理器页面,发现每个文件的大小似乎比在我的电脑上小(例如:54.33MB而不是大约57MB)。可能是因为不同的文件系统,...?
总结问题2:我上传一个大文件,在线上看起来比在我的笔记本电脑上小,然后我下载它,实际上比原来的版本要大。很奇怪,不是吗?有什么想法吗?谢谢您的帮助!
这是我的server.js文件:
var http = require('http');
var url = require("url");
var express = require('express');
var querystring = require('querystring');
var fs = require('fs');
var path = require('path');
var azure = require('azure');
var multiparty = require('multiparty');
var tools = require('./tools.js');
var app = express();
app.use(express.logger("dev"));
var port = process.env.PORT || 1337;
var containerName = 'publicblobs';
app.use('/public', express.static('./public'));
/*
* \brief Displays upload form
*/
app.get('(/|/upload/?)', function(req, res) {
res.redirect('/public/upload.html');
});
/*
* \brief Handles upload post request.
*/
app.post('/upload/request/?', function (req, res) {
var blobService = azure.createBlobService();
var form = new multiparty.Form();
var currentFileName = 'undefinedCurrentFileName';
blobService.createContainerIfNotExists(containerName
, {publicAccessLevel : 'blob'}
, function(error){
if(!error){
// Container exists and is public
} else {
res.render('log.ejs', {log: error.message});
}
});
function gotPart(part) {
if (part.filename) {
console.log("New file received !");
currentFileName = part.filename;
var size = part.byteCount;
console.log("file size : " + size);
var onError = function(error) {
if (error) {
console.log("blobService.createBlockBlobFromStream : on error");
res.render('log.ejs', {log: error.message});
} else {
console.log("onError() : No error");
}
};
blobService.createBlockBlobFromStream(containerName, currentFileName, part, size, onError);
} else {
console.log("New part received (not a file)");
form.handlePart(part);
}
}
form.on('part', gotPart);
function reqEnd() {
console.log("Upload completed!");
res.redirect('/upload/complete/?'+
// 'url='+req.get('host')+'/library/download/'+targetFileName+//'+req.get('host')+'
'&fileName='+currentFileName+
'&result=success');
}
req.on('end', reqEnd);
function handleErrorCallback(error) { // inspired from https://dev59.com/f2Ml5IYBdhLWcg3we283
var errorLog = "There was an error while receiving the request. The client may have put an end to the connection : " + error;
console.log(errorLog);
}
req.on('error', handleErrorCallback);
form.on('error', handleErrorCallback);
form.parse(req);
});
/*
* \brief Returns the file to the user.
*/
app.get('/library/download/:fileName', function(req, res) {
fs.readFile('./public/uploaded/'+req.params.fileName, function(error,data){
res.end(data);
});
});
/*
* \brief Inform the user about his uploaded file (and about error if need be)
*/
app.get('/upload/complete/?', function(req, res) {
var params = querystring.parse(url.parse(req.url).query);
res.setHeader('Content-Type', 'text/html');
res.charset = 'utf8';
if (params['result'] === 'success') {
res.render('uploadComplete.ejs', {log: 'File '+params['fileName']+' uploaded to ', url: url.parse('http://'+process.env['AZURE_STORAGE_ACCOUNT']+'.blob.core.windows.net/'+containerName+'/'+params['fileName']).href});
} else {
res.render('uploadComplete.ejs', {log: 'An error occurred while uploading '+params['fileName']+' : '+params['log'], url: ''});
}
});
/*
* \brief Handles wrong addresses
*/
app.use(function(req, res, next){
res.setHeader('Content-Type', 'text/plain');
res.charset = 'utf8';
console.log("Redirection due to the fact that the page has not been found.");
res.redirect('/upload');
});
app.listen(port);
这是我使用Bootstrap和jQuery创建的表单:
<div class="container">
<div class="starter-template">
<form class="form-signin" role="form" action="/upload/request" method="post" enctype="multipart/form-data">
<h2 class="form-signin-heading">Select a file to upload</h2>
<label>
<input type="file" name="filename2" id="filename2" class="form-control" required>
</label>
<button class="btn btn-lg btn-primary btn-block" type="submit">Upload</button>
</form>
</div>
这是我的web.config文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<webSocket enabled="false" />
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?" />
</rule>
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824"/>
</requestFiltering>
</security>
</system.webServer>
<system.web>
<httpRuntime maxRequestLength="2097152"/>
</system.web>
</configuration>