【问题标题】:Using HTML5 FileReader, c#, and jquery to upload file使用 HTML5 FileReader、c# 和 jquery 上传文件
【发布时间】:2014-09-22 00:13:50
【问题描述】:

我正在尝试将文件上传到 c# 中的通用 HttpHandler。我使用拖放事件获取文件:

 $s("#dropArea")
    .on("drop", function(e) {
        e.preventDefault && e.preventDefault();

        var file = e.originalEvent.dataTransfer.files[0];

        var reader = new FileReader();

    reader.onload = function(evt) {
        $s.ajax({
            url: MY_SERVER_URL,
            type: "POST",
            data: reader.result,
            headers: {
                "x-file-name": file.name
            }                
        });
    };
    reader.readAsDataURL(file);

这似乎工作正常,但是当发布到 ashx 页面时,我尝试像这样解码图像:

var form = context.Request.Form[0];
var attachment = form.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries)[1];

byte[] data = Convert.FromBase64String(attachment);

当我尝试将byte[] data 写入磁盘时,生成的文件不正确。我哪里错了?

edit:我也尝试过使用 FormData,但是 Request.Form 和 Request.Files 集合总是空的,我必须手动解析边界。这是我用来执行此操作的代码:

var formData = new FormData();
    formData.append(file.name, file);

    $s.ajax({
        url: MY_SERVER_URL,
        type: "POST",
        data: formData,
        processData: false,
        contentType: 'multipart/form-data',
        mimeType: 'multipart/form-data',
        headers: {
            "x-file-name": file.name            
    });

【问题讨论】:

  • 那你为什么不像普通人一样,使用formData对象来上传图片呢?
  • @adeneo 因为我这样做时 Request.Form 集合总是空的。我在 jQuery 中将内容类型设置为“multipart/form-data”,它只是通过 Request.InputStream,然后需要我解析边界。
  • 第二个,去掉headers,设置contentType为false,看看是否有效。
  • @adeneo 谢谢,就是这样。为什么将 contentType 设置为 false 会改变它?我没有在 jquery 文档中看到描述该行为的地方。
  • 将 contentType 设置为 false 会强制 jQuery 不添加 Content-Type 标头,并随后删除边界字符串,它必须设置为 false 才能处理文件。

标签: c# javascript jquery html


【解决方案1】:

使用 jQuery 的$.ajax 发送文件时,必须将processDatacontentType 选项设置为false

processData 设置为false 可确保jQuery 不会以任何方式处理formData 对象。

contentType 设置为 false 可确保 jQuery 不会添加边界,这是它通常会做的事情。也就是jQuery添加了contentType、一个边界,所以看起来像:

Content-Type=multipart/form-data; boundary=----------------993434535254

我们不希望 jQuery 设置某个边界,因为这样服务器端将无法理解发生了什么,所以为了避免它,contentType 必须 设置为 false发送文件时。

var formData = new FormData();

    formData.append(file.name, file);

$s.ajax({
    url: MY_SERVER_URL,
    type: "POST",
    data: formData,
    processData: false,
    contentType: false,
});

这就是使用 jQuery 发送文件所需的所有选项

【讨论】:

    【解决方案2】:

    您在哪个浏览器上试用过这个?你用的是什么版本的jquery?包含更多细节以增加您找到答案的机会。

    由于您要上传图像,因此您可能希望使用可以调整大小/转换或其他任何内容的组件,或者您的用户可能会上传错误的类型,因此可能需要考虑使用可以帮助您解决此问题的组件。

    在网络上上传文件可能会很棘手,与其尝试重新发明轮子,不如为自己省点麻烦,并选择一个像 plupload 这样人们已经工作多年的库。

    即使您让上面的代码在您的特定情况下工作并且您认为它有效,它很可能在您未测试的每个场景中都存在错误。对于网络文件上传,每一个小细节都必须准确无误,否则将无法正常工作。如果您的任何文件很大,具体取决于您使用的网络服务器,您可能需要调整这些设置等。

    我不知道您的代码有什么问题,但我知道要正确执行此操作比您上面的代码要复杂得多。

    【讨论】:

      猜你喜欢
      • 2013-12-11
      • 1970-01-01
      • 1970-01-01
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      • 2021-04-18
      相关资源
      最近更新 更多