【问题标题】:Input type = "file" loses file automatically?输入类型=“文件”自动丢失文件?
【发布时间】:2014-12-28 04:06:03
【问题描述】:

我有两个文件类型的输入,一个在部分视图中,另一个在主页中

局部视图

<input type="file" name="image" id="image" onchange="readURL(this)"/>

在主页面

<input type="file" name="userProfilePic" id="userProfilePic" style="display:none" />

我想要的是,当用户在可见文件上传上更改 image/file 时,image/file 也应该在主/其他输入上更新。这是我的代码。

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#imagePreview').attr('src', e.target.result);
        }
        reader.readAsDataURL(input.files[0]);
        // window['profilePic'] = input.files[0];
        $('#userProfilePic').get(0).files[0] = input.files[0];
        return false;
    }

错误

这个错误很奇怪,当我打开我的控制台并检查文件时,它有时会出现,然后又不会。

在我的控制台窗口中

$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
undefined

而且这不是第一次发生。有时说,它显示了 5-6 次的值,然后第 7 次它不会...

$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
undefined

这就是我所有的代码,没有其他代码。现在,正如您在代码中看到的,我还将window[profilePic] 设置为文件对象。但是,如果我在控制台窗口中检查它,无论如何它总是显示?这是怎么回事?

问题

我需要提交表单,但是当我这样做时,图像(输入文件)被作为空文件发送,但有时作为有效文件发送。正如我之前解释的,当我检查控制台中的值时,它第一次显示,或者随机显示了几次,然后突然消失了,而我在窗口(@98​​7654329@)上设置的变量总是有那个文件对象。
如果有人想知道,用户实际选择文件的原始/可见文件输入始终具有该值。

【问题讨论】:

  • 我已经放置了一个更新的答案。

标签: html asp.net-mvc file input


【解决方案1】:

出于安全原因,您不能这样做,所有通过input type="file" 上传的文件都必须由用户手动完成。

但是,只要用户无论如何都会上传图片,您应该在服务器端脚本中完成所有您想要的过程。

更多信息,请参考这篇文章:

How to set a value to a file input in HTML?

【讨论】:

  • 还有其他解决方法吗?如果您已完全阅读我的问题,我希望您理解我的要求。我可以通过其他方式发送吗?
  • 另外,一个问题,听起来可能很愚蠢,但是浏览器如何知道它是由代码完成的还是用户手动选择了一个文件?
  • @Razort4x 回答您的第一个问题是的,有一个解决方法,如果我知道您之后会做什么,我可以提供帮助,假设设置了隐藏的输入文件,为您提供确切的详细信息,对于第二个问题,你可以参考W3帖子:w3.org/TR/html-markup/input.file.html,不是只读值的属性,这就是函数的构建方式,所以浏览器不知道它是否以编程方式设置,问题是你不能这样做,所以浏览器不知道必须检查。
  • 感谢 w3 链接,但它让我再次思考,它是如何在内部工作的。我的意思是如果用户选择一个文件,如果控件是只读的,文件值是如何设置的?无论如何,这无关紧要。关于我的第一个问题,这是用户上传的图像,因此我对其进行处理并将其设置为用户的个人资料图片。我在动作中将它发布在 HttpPostedFileBase 中。你觉得可以做什么?
  • @Razort4x 在这种情况下什么是有意义的,永远不会上传同一张照片两次!解决方案很简单,只需将图片一次上传到服务器,然后将用户的个人资料图片和任何具有相同图片的内容指向同一个文件,以防您想要裁剪图像、调整大小或任何其他过程,所有这些都可以通过脚本完成,但永远不要两次上传相同的文件。
【解决方案2】:

为什么你尝试对同一个文件使用两个输入文件?

如果您尝试使用输入文件和额外数据在 PartialView 中创建表单?我在这里回答了一个非常相似的问题:

File upload in MVC when used in bootstrap modal returns null

1) 制作一个用于表单的模型,其中包含表单的所有元素,

2) 在局部视图的第一行声明模型

3) 将模型作为参数传递给 post 函数。

4)你使用了一个Partial视图,也可以在不同的页面中使用这个视图,你需要指定控件来处理表单。

代码示例:

型号:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

    public class PartialFormModel
    {
        [Required]
        [StringLength(200)]
        public string FileName { get; set; }

        [StringLength(200)]
        public string Title { get; set; }

        [StringLength(1000)]
        public string Description { get; set; }

        public int? Order { get; set; }

        [NotMapped]
        public HttpPostedFileBase ImageFile { get; set; }
    }

部分视图:

@model YOURSPACENAME.Models.PartialFormModel    

@using (Html.BeginForm("YourActionName", "YourControllerName", FormMethod.Post, new { @class = "form-horizontal", @role = "form", @enctype="multipart/form-data" })) 
    {
        @Html.AntiForgeryToken()

        <div class="form-group">
                @Html.LabelFor(model => model.FileName, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.FileName, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.FileName, "", new { @class = "text-danger" })
                </div>
            </div>

    <div class="form-group">
                @Html.LabelFor(model => model.ImageFile, new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.TextBoxFor(m => m.ImageFile, new { @class = "form-control", type = "file" })
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
    }

控制器

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult YourActionName(PartialFormModel obj)
{
    if (ModelState.IsValid)
    {
        //your options
    }
    return PartialView("_EditSlider");
}

【讨论】:

    【解决方案3】:

    考虑到:

    1. 出于安全原因,您不能将value 设置为输入type="file" 以编程方式。
    2. 更改&lt;input&gt; 的类型会在某些情况下引发安全错误 浏览器(旧 IE 和 Firefox 版本)。

    我实际上不知道你想要什么。但我建议您创建一个新的input 元素,将其类型设置为您想要的类型,例如file,并根据您的需要设置其属性。像这样:

    <script>
    function createInputType(_type, _value, _name, _id, _class) {
        var newObject = document.createElement('input');
        newObject.type = _type;
        newObject.value = _value;
        newObject.name = _name;
        newObject.id = _id;
        newObject.className = _class;
        return newObject;
    }
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-06
      • 2012-07-31
      • 2021-10-24
      • 2014-10-23
      • 1970-01-01
      • 2020-06-22
      相关资源
      最近更新 更多