提问人:Franco 提问时间:10/17/2023 最后编辑:Franco 更新时间:10/17/2023 访问量:31
Blueimp jQuery 文件上传 - 上传到不在内存中的特定文件夹
Blueimp jQuery File Upload - Upload to Specific Folder not in memory
问:
我正在使用 blueimp jquery 文件上传 (https://github.com/blueimp/jQuery-File-Upload),并按照演示和文档开发了一个用于上传文件的页面。
环境:Asp.Net Web 窗体 - .NET 4.6.1 - jquery 3.3.1
我使用了一个处理程序。 实际问题是一切似乎都很好,但是我要上传的文件不会存储在文件夹中。
似乎只在内存中起作用。 加载页面时,位于特定文件夹中的文件已收缩(为了测试,我只放置了 1 个名为 test.jpg 的文件)。 在我按下按钮上传后,处理程序中的代码已执行,但 Request.HttpMethod 始终为 GET。 没有引发错误,并且在末尾页面显示文件列表,其中包含 2 次出现相同的文件 (test.jpg)。
也许问题是处理程序是用 c# 编写的,调用方页面是用 vb.net 编写的?
这是内容 ASPX 页面
<%@ Page Language="vb" AutoEventWireup="false" MasterPageFile="~/Site.Master" CodeBehind="FunctionUpload.aspx.vb" Inherits="Monitor.FunctionUpload" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="FeaturedContent" runat="server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="MainContent" runat="server">
<link rel="Stylesheet" type="text/css" href="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/css/jquery.fileupload.css")%>"/>
<link rel="Stylesheet" type="text/css" href="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/css/jquery.fileupload-ui.css")%>"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="container">
<h1>jQuery File Upload Demo</h1>
<blockquote class="description">
<p>
File Upload widget with multiple file selection, drag&drop
support, progress bars, validation and preview images, audio and video
for jQuery.<br />
Supports cross-domain, chunked and resumable file uploads and
client-side image resizing.<br />
Works with any server-side platform (PHP, Python, Ruby on Rails, Java,
Node.js, Go etc.) that supports standard HTML form file uploads.
</p>
</blockquote>
<div id="fileupload">
<noscript>
<input type="hidden" name="redirect"
value="https://blueimp.github.io/jQuery-File-Upload/"
/></noscript>
<div class="row fileupload-buttonbar">
<div class="col-lg-7">
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
<input type="file" name="files[]" multiple />
</span>
<button type="button" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
<button type="button" class="btn btn-danger delete">
<i class="glyphicon glyphicon-trash"></i>
<span>Delete selected</span>
</button>
<input type="checkbox" class="toggle" />
<span class="fileupload-process"></span>
</div>
<div class="col-lg-5 fileupload-progress fade">
<div
class="progress progress-striped active"
role="progressbar"
aria-valuemin="0"
aria-valuemax="100"
>
<div
class="progress-bar progress-bar-success"
style="width:0%;"
></div>
</div>
<div class="progress-extended"> </div>
</div>
</div>
<table role="presentation" class="table table-striped">
<tbody class="files"></tbody>
</table>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Demo Notes</h3>
</div>
<div class="panel-body">
<ul>
<li>
The maximum file size for uploads in this demo is
<strong>999 KB</strong> (default file size is unlimited).
</li>
<li>
Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in
this demo (by default there is no file type restriction).
</li>
<li>
Uploaded files will be deleted automatically after
<strong>5 minutes or less</strong> (demo files are stored in
memory).
</li>
<li>
You can <strong>drag & drop</strong> files from your desktop
on this webpage (see
<a
href="https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support"
>Browser support</a
>).
</li>
<li>
Please refer to the
<a href="https://github.com/blueimp/jQuery-File-Upload"
>project website</a
>
and
<a href="https://github.com/blueimp/jQuery-File-Upload/wiki"
>documentation</a
>
for more information.
</li>
<li>
Built with the
<a href="https://getbootstrap.com/">Bootstrap</a> CSS framework
and Icons from <a href="https://glyphicons.com/">Glyphicons</a>.
</li>
</ul>
</div>
</div>
</div>
<!-- The blueimp Gallery widget -->
<div
id="blueimp-gallery"
class="blueimp-gallery blueimp-gallery-controls"
data-filter=":even"
>
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev">‹</a>
<a class="next">›</a>
<a class="close">×</a>
<a class="play-pause"></a>
<ol class="indicator"></ol>
</div>
<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
<td>
<span class="preview"></span>
</td>
<td>
{% if (window.innerWidth > 480 || !o.options.loadImageFileTypes.test(file.type)) { %}
<p class="name">{%=file.name%}</p>
{% } %}
<strong class="error text-danger"></strong>
</td>
<td>
<p class="size">Processing...</p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
</td>
<td>
{% if (!o.options.autoUpload && o.options.edit && o.options.loadImageFileTypes.test(file.type)) { %}
<button class="btn btn-success edit" data-index="{%=i%}" disabled>
<i class="glyphicon glyphicon-edit"></i>
<span>Edit</span>
</button>
{% } %}
{% if (!i && !o.options.autoUpload) { %}
<button class="btn btn-primary start" disabled>
<i class="glyphicon glyphicon-upload"></i>
<span>Start</span>
</button>
{% } %}
{% if (!i) { %}
<button class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
{% } %}
</td>
</tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-download fade">
<td>
<span class="preview">
{% if (file.thumbnailUrl) { %}
<a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
{% } %}
</span>
</td>
<td>
{% if (window.innerWidth > 480 || !file.thumbnailUrl) { %}
<p class="name">
{% if (file.url) { %}
<a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
{% } else { %}
<span>{%=file.name%}</span>
{% } %}
</p>
{% } %}
{% if (file.error) { %}
<div><span class="label label-danger">Error</span> {%=file.error%}</div>
{% } %}
</td>
<td>
<span class="size">{%=o.formatFileSize(file.size)%}</span>
</td>
<td>
{% if (file.deleteUrl) { %}
<button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
<input type="checkbox" name="delete" value="1" class="toggle">
{% } else { %}
<button class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
{% } %}
</td>
</tr>
{% } %}
</script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/vendor/jquery.ui.widget.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/JavaScript-Templates/tmpl.min.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/JavaScript-Templates/load-image.all.min.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/JavaScript-Templates/canvas-to-blob.min.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/JavaScript-Templates/jquery.blueimp-gallery.min.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.iframe-transport.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.fileupload.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.fileupload-process.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.fileupload-image.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.fileupload-audio.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.fileupload-video.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.fileupload-validate.js")%>" type="text/javascript"></script>
<script src="<%=Page.ResolveClientUrl("~/js/libs/jquery.fileupload/js/jquery.fileupload-ui.js")%>" type="text/javascript"></script>
<!-- The main application script -->
<script src="demo.js"></script>
<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->
<!--[if (gte IE 8)&(lt IE 10)]>
<script src="js/cors/jquery.xdr-transport.js"></script>
<![endif]-->
</asp:Content>
这是名为 UploadHandler_4_0.aspx 的处理程序
<%@ Page ContentType="application/json" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Runtime.Serialization" %>
<%@ Import Namespace="System.Runtime.Serialization.Json" %>
<script language="C#" runat="server">
private static readonly FilesDisposition FILES_DISPOSITION = FilesDisposition.ServerRoot;
//private static readonly string FILES_PATH = @"/files";
private static readonly string FILES_PATH = "~/Function/server/upload";
private static readonly string FILE_QUERY_VAR = "file";
private static readonly string FILE_GET_CONTENT_TYPE = "application/octet-stream";
private static readonly int ATTEMPTS_TO_WRITE = 3;
private static readonly int ATTEMPT_WAIT = 100; //msec
private static readonly int BUFFER_SIZE = 4 * 1024 * 1024;
private enum FilesDisposition
{
ServerRoot,
HandlerRoot,
Absolute
}
private static class HttpMethods
{
public static readonly string GET = "GET";
public static readonly string POST = "POST";
public static readonly string DELETE = "DELETE";
}
[DataContract]
private class FileResponse
{
[DataMember]
public string name;
[DataMember]
public long size;
[DataMember]
public string type;
[DataMember]
public string url;
[DataMember]
public string error;
[DataMember]
public string deleteUrl;
[DataMember]
public string deleteType;
}
[DataContract]
private class UploaderResponse
{
[DataMember]
public FileResponse[] files;
public UploaderResponse(FileResponse[] fileResponses)
{
files = fileResponses;
}
}
private string CreateFileUrl(string fileName, FilesDisposition filesDisposition)
{
switch (filesDisposition)
{
case FilesDisposition.ServerRoot:
// 1. files directory lies in root directory catalog WRONG
return String.Format("{0}{1}/{2}", Request.Url.GetLeftPart(UriPartial.Authority),
FILES_PATH, Path.GetFileName(fileName));
case FilesDisposition.HandlerRoot:
// 2. files directory lays in current page catalog WRONG
return String.Format("{0}{1}{2}/{3}", Request.Url.GetLeftPart(UriPartial.Authority),
Path.GetDirectoryName(Request.CurrentExecutionFilePath).Replace(@"\", @"/"), FILES_PATH, Path.GetFileName(fileName));
case FilesDisposition.Absolute:
// 3. files directory lays anywhere YEAH
return String.Format("{0}?{1}={2}", Request.Url.AbsoluteUri, FILE_QUERY_VAR, HttpUtility.UrlEncode(Path.GetFileName(fileName)));
default:
return String.Empty;
}
}
private FileResponse CreateFileResponse(string fileName, long size, string error)
{
return new FileResponse()
{
name = Path.GetFileName(fileName),
size = size,
type = String.Empty,
url = CreateFileUrl(fileName, FILES_DISPOSITION),
error = error,
deleteUrl = CreateFileUrl(fileName, FilesDisposition.Absolute),
deleteType = HttpMethods.DELETE
};
}
private void SerializeUploaderResponse(List<FileResponse> fileResponses)
{
DataContractJsonSerializer Serializer = new DataContractJsonSerializer(typeof(UploaderResponse));
Serializer.WriteObject(Response.OutputStream, new UploaderResponse(fileResponses.ToArray()));
}
private void FromStreamToStream(Stream source, Stream destination)
{
int BufferSize = source.Length >= BUFFER_SIZE ? BUFFER_SIZE : (int)source.Length;
long BytesLeft = source.Length;
byte[] Buffer = new byte[BufferSize];
int BytesRead = 0;
while (BytesLeft > 0)
{
BytesRead = source.Read(Buffer, 0, BytesLeft > BufferSize ? BufferSize : (int)BytesLeft);
destination.Write(Buffer, 0, BytesRead);
BytesLeft -= BytesRead;
}
}
protected void Page_Load(object sender, EventArgs e)
{
string FilesPath;
switch (FILES_DISPOSITION)
{
case FilesDisposition.ServerRoot:
FilesPath = Server.MapPath(FILES_PATH);
break;
case FilesDisposition.HandlerRoot:
FilesPath = Server.MapPath(Path.GetDirectoryName(Request.CurrentExecutionFilePath) + FILES_PATH);
break;
case FilesDisposition.Absolute:
FilesPath = FILES_PATH;
break;
default:
Response.StatusCode = 500;
Response.StatusDescription = "Configuration error (FILES_DISPOSITION)";
return;
}
// prepare directory
if (!Directory.Exists(FilesPath))
{
Directory.CreateDirectory(FilesPath);
}
string QueryFileName = Request[FILE_QUERY_VAR];
string FullFileName = null;
string ShortFileName = null;
//if (!String.IsNullOrEmpty(QueryFileName))
if (QueryFileName != null) // param specified, but maybe in wrong format (empty). else user will download json with listed files
{
ShortFileName = HttpUtility.UrlDecode(QueryFileName);
FullFileName = String.Format(@"{0}\{1}", FilesPath, ShortFileName);
if (QueryFileName.Trim().Length == 0 || !File.Exists(FullFileName))
{
Response.StatusCode = 404;
Response.StatusDescription = "File not found";
Response.End();
return;
}
}
if (Request.HttpMethod.ToUpper() == HttpMethods.GET)
{
if (FullFileName != null)
{
Response.ContentType = FILE_GET_CONTENT_TYPE;
Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}{1}", Path.GetFileNameWithoutExtension(ShortFileName), Path.GetExtension(ShortFileName).ToUpper()));
using (FileStream FileReader = new FileStream(FullFileName, FileMode.Open, FileAccess.Read))
{
FromStreamToStream(FileReader, Response.OutputStream);
Response.OutputStream.Close();
}
Response.End();
return;
}
else
{
List<FileResponse> FileResponseList = new List<FileResponse>();
string[] FileNames = Directory.GetFiles(FilesPath);
foreach (string FileName in FileNames)
{
FileResponseList.Add(CreateFileResponse(FileName, new FileInfo(FileName).Length, String.Empty));
}
SerializeUploaderResponse(FileResponseList);
}
}
else if (Request.HttpMethod.ToUpper() == HttpMethods.POST)
{
List<FileResponse> FileResponseList = new List<FileResponse>();
for (int FileIndex = 0; FileIndex < Request.Files.Count; FileIndex++)
{
HttpPostedFile File = Request.Files[FileIndex];
string FileName = String.Format(@"{0}\{1}", FilesPath, Path.GetFileName(File.FileName));
string ErrorMessage = String.Empty;
for (int Attempts = 0; Attempts < ATTEMPTS_TO_WRITE; Attempts++)
{
ErrorMessage = String.Empty;
if (System.IO.File.Exists(FileName))
{
FileName = String.Format(@"{0}\{1}_{2:yyyyMMddHHmmss.fff}{3}", FilesPath, Path.GetFileNameWithoutExtension(FileName), DateTime.Now, Path.GetExtension(FileName));
}
try
{
using (Stream FileStreamWriter = new FileStream(FileName, FileMode.CreateNew, FileAccess.Write))
{
FromStreamToStream(File.InputStream, FileStreamWriter);
}
}
catch (Exception exception)
{
ErrorMessage = exception.Message;
System.Threading.Thread.Sleep(ATTEMPT_WAIT);
continue;
}
break;
}
FileResponseList.Add(CreateFileResponse(File.FileName, File.ContentLength, ErrorMessage));
}
SerializeUploaderResponse(FileResponseList);
}
else if (Request.HttpMethod.ToUpper() == HttpMethods.DELETE)
{
bool SuccessfullyDeleted = true;
try
{
File.Delete(FullFileName);
}
catch
{
SuccessfullyDeleted = false;
}
Response.Write(String.Format("{{\"{0}\":{1}}}", ShortFileName, SuccessfullyDeleted.ToString().ToLower()));
}
else
{
Response.StatusCode = 405;
Response.StatusDescription = "Method not allowed";
Response.End();
return;
}
Response.End();
}
</script>
这是演示.js
$(function() {
'use strict';
// Initialize the jQuery File Upload widget:
$('#fileupload').fileupload({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
url: 'server/asp_net/UploadHandler_4_0.aspx'
});
// Enable iframe cross-domain access via redirect option:
$('#fileupload').fileupload(
'option',
'redirect',
window.location.href.replace(/\/[^/]*$/, '/cors/result.html?%s')
);
if (window.location.hostname === 'blueimp.github.io') {
// Demo settings:
$('#fileupload').fileupload('option', {
url: '//jquery-file-upload.appspot.com/',
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/.test(
window.navigator.userAgent
),
maxFileSize: 999000,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
});
// Upload server status check for browsers with CORS support:
if ($.support.cors) {
$.ajax({
url: '//jquery-file-upload.appspot.com/',
type: 'HEAD'
}).fail(function() {
$('<div class="alert alert-danger"/>')
.text('Upload server currently unavailable - ' + new Date())
.appendTo('#fileupload');
});
}
} else {
// Load existing files:
$('#fileupload').addClass('fileupload-processing');
console.log($('#fileupload').fileupload('option', 'url'));
$.ajax({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
url: $('#fileupload').fileupload('option', 'url'),
dataType: 'json',
context: $('#fileupload')[0]
})
.always(function() {
$(this).removeClass('fileupload-processing');
})
.done(function(result) {
$(this)
.fileupload('option', 'done')
// eslint-disable-next-line new-cap
.call(this, $.Event('done'), { result: result });
});
}
});
答: 暂无答案
评论