- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在管理一个 Web 应用程序,该应用程序接受用户的文件,然后将其上传到服务器中的文件位置。为了满足大文件(100 MB 以上)的需要,我决定使用 blob.slice 方法。我的问题是,文件上传并尝试下载后,文件大小是原始大小的两倍,因此导致文件损坏。我将展示从客户端到服务器端的数据流,以展示上传方法的逐步操作。
该指令是输入 type="file"的 HTML 和 blob 切片逻辑所在的位置。
客户端
//Directive
var template = [
'<div class="file-input">',
'<div>',
'<input type="text" ng:model="fileinfo.meta.name" disabled />',
'<div class="filebrowse">',
'<button type="button" class="browsemodal">Browse</button>',
'<input type="file"></input>',
'</div>',
'</div>',
'</div>'
].join('');
module.exports.init = function (app) {
app.directive('fileInput', [
function () {
return {
restrict: 'E',
template: template,
replace: true,
scope: {
fileinfo : '=ngModel'
},
link: function (scope, element) {
element.bind('change', function (ev) {
var fileSize = ev.target.files[0].size;
var chunkSize = 64 * 1024;
var offset = 0;
var self = this;
var chunkReaderBlock = null;
var readEventHandler = function (evt) {
offset += evt.target.result.length;
scope.fileinfo.meta = ev.target.files[0];
scope.fileinfo.data = ev.target.files[0];
scope.fileinfo.sampleData.push(evt.target.result);
if (offset >= fileSize) {
return;
}
chunkReaderBlock(offset, chunkSize, ev.target.files[0]);
};
chunkReaderBlock = function (_offset, length, _file) {
var reader = new FileReader();
var blob = _file.slice(_offset, length + _offset);
reader.onload = readEventHandler;
reader.readAsText(blob);
};
chunkReaderBlock(offset, chunkSize, ev.target.files[0]);
});
}
}
}
]);
};
scope.fileinfo 表示工厂中名为 documentInfoModel 的属性,如下面的代码片段所示。
//Factory
documentInfoModel: function () {
var self = this;
self.meta = null;
self.data = null;
self.sampleData = [];
return self;
现在,只要我点击上传按钮,它就会触发 Controller 中名为saveData的函数。该函数将通过 documentService.upsertDocument 方法从服务器端调用 http.Post 到 API。该 API 名为 AddFile。请参阅下面的完整详细信息。
//Controller
$scope.saveData = function () {
documentService.upsertDocument($scope.fileInfoItem).then(function (data) {
//File was uploaded successfully
};
};
服务器端
public HttpResponseMessage AddFile(HttpRequestMessage request, [FromBody] DocumentInfoModel file)
{
using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 30, 0)))
{
try
{
StringBuilder sb = new StringBuilder();
foreach (string text in file.sampleData)
sb.Append(text);
byte[] data = Encoding.Unicode.GetBytes(sb.ToString());
var fileLocation = "C:\Temp\";
var targetFileName = file.data;
if (!Directory.Exists(fileLocation))
Directory.CreateDirectory(fileLocation);
File.WriteAllBytes(targetFileName, data);
}
catch()
{}
return request.CreateResponse(HttpStatusCode.OK);
}
谁能帮我找出代码中的任何问题吗?如果有帮助的话,我也会把下载 API 放在这里。非常感谢!
private HttpResponseMessage Download(string fileName)
{
var filePath = "C:\Temp\";
var res = new HttpResponseMessage();
if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
{
res.Content = new StreamContent(File.OpenRead(filePath));
res.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
res.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
res.StatusCode = HttpStatusCode.OK;
}
else
res.StatusCode = HttpStatusCode.InternalServerError;
return res;
}
最佳答案
在向同事寻求帮助后,我们找到了解决问题的方法。也许我只是不知道在上传大文件时如何正确实现 FileReader 的异步方法,所以我们决定使用不同的方法。我们做的第一件事是删除指令内的模板并将指令修改为如下所示:
//Directive
app.directive('fileInput', [
function () {
return {
restrict: 'EA',
replace: true,
scope: {
fileinfo: '=ngModel'
},
link: function (scope, element) {
element.bind('change', function (ev) {
scope.$apply(function () {
var val = element[0].files[0];
scope.fileinfo.fileName = ev.target.files[0];
scope.fileinfo.file = val;
});
});
}
}
}
]);
然后我们在 HTML 文件本身内创建了模板(见下文):
<input type="text" ng:model="fileInfoItem.fileName" disabled />
<div class="filebrowse">
<button type="button" class="browsemodal">Browse</button>
<input name="file" file-input="fileinfo" ng-model="fileInfoItem" type="file" />
</div>
接下来,在 Controller 中我们使用 FormData 来存储文件,然后将其发送到 API。
//Controller
$scope.saveDocument = function () {
var fd = new FormData();
fd.append('file', $scope.fileInfoItem.file);
documentService.upsertDocument($scope.fileInfoItem, fd)
.then(function (data) {
//Upload was successful.
};
};
//Services
upsertDocument: function (fileInfoItem, data) {
console.log(data);
var payload = {
FileName: fileInfoItem.fileName
};
return apiCall = $http.post(API_ENDPOINT.upsertDocument(fileInfoItem.docId), payload {})
.then(function (ret) {
return $http.post(API_ENDPOINT.upsertDocumentFile(ret.data), data, {
withCredentials: false,
headers: {
'Content-Type': undefined
},
transformRequest: angular.identity
});
});
},
我们创建两个 API 的原因是我们无法将帖子正文中的文件和对象负载传递给单个 API。这可能不是最好的解决方案,但它绝对适合我们的应用程序。
关于javascript - 上传后双倍大小的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41069921/
我有以下正则表达式 /[a-zA-Z0-9_-]/ 当字符串只包含从 a 到z 大小写、数字、_ 和 -。 我的代码有什么问题? 能否请您向我提供一个简短的解释和有关如何修复它的代码示例? //var
我是一名优秀的程序员,十分优秀!