如何在HTML中为文件输入设置值?

469

我该如何设置它的值?

<input type="file" />

3
我已经在这里完成了一篇完整的参考文献和最新(2013年12月)答案:Remember and Repopulate File Input - GitaarLAB
1
  1. 文件输入中默认值的问题并非出于安全原因,而是浏览器“没有充分的理由未能实现它”:请参阅此深度报告。2) 一个简单的解决方案是在文件输入上使用文本输入框,就像这里。当然,您需要一些代码来发送文件,现在使用文本输入框中的值而不是文件输入框中的值。在我的情况下,做HTA应用程序,这不是问题,我根本不使用表单。
- msillano
10个回答

664

由于安全原因,您不能将其设置为客户端磁盘文件系统路径。

想象一下:

<form name="foo" method="post" enctype="multipart/form-data">
    <input type="file" value="c:/passwords.txt">
</form>
<script>document.foo.submit();</script>

你不想访问的网站能够做到这一点,对吧? =)

正如这个答案中所述,您只能将其设置为公共可访问的网络资源,但这显然不同于客户端的磁盘文件系统路径,在这种情况下是无用的。


180

你无法直接设置文件输入框的值。

唯一的方法是用户选择一个文件来设置文件输入框的值。

这么做是基于安全考虑。否则,你将能够创建一个自动上传客户端计算机特定文件的 JavaScript。


1
如果我想将文件输入的值设置为一些生成的内容(而不是来自磁盘),该怎么办? - Eugene Mala
1
@EugeneMala:文件输入的值是用户选择的文件。您不能在该值中放置任何其他内容。 - Guffa
2
@Guffa 其实那是错误的,你可以将 blob 值放入文件输入值中,它不一定要来自用户,但是确实不能通过它在用户的计算机上放置东西。 - Syed M. Sannan

67
我写了一个完整的示例,它可以将URL加载到文件输入中,并显示预览。 enter image description here 你可以在这里检查 1 https://vulieumang.github.io/vuhocjs/file2input-input2file/ 简而言之,你可以使用这个函数。
function loadURLToInputFiled(url){
  getImgURL(url, (imgBlob)=>{
    // Load img blob to input
    // WIP: UTF8 character error
    let fileName = 'hasFilename.jpg'
    let file = new File([imgBlob], fileName,{type:"image/jpeg", lastModified:new Date().getTime()}, 'utf-8');
    let container = new DataTransfer(); 
    container.items.add(file);
    document.querySelector('#file_input').files = container.files;
    
  })
}
// xmlHTTP return blob respond
function getImgURL(url, callback){
  var xhr = new XMLHttpRequest();
  xhr.onload = function() {
      callback(xhr.response);
  };
  xhr.open('GET', url);
  xhr.responseType = 'blob';
  xhr.send();
}

3
太疯狂了,前四个答案声称不可能(获得600多票),而这个答案却如此优雅地解决了问题,对于我的用例效果非常好。 - Omri Luzon
@aussiedan,您的意思是想将多个图像URL加载到一个输入中还是多个输入中? - Đinh Tiến Vũ
2
@OmriLuzon 没问题 :). 我花了很多时间才找到这种方法,希望更多的人能够找到它。 - Đinh Tiến Vũ
这在我的本地环境中是有效的。但是,当我尝试从s3加载图像时,它被CORS策略阻止了。我应该如何允许我的代码访问来自s3的图像?我尝试了这里的答案https://stackoverflow.com/a/67024725/13933721以启用cors策略,但仍然无法获取图像。 - Mr. Kenneth
这与其他解释如何使用XMLHttpRequest();的答案有何不同? - HoldOffHunger
显示剩余4条评论

62

虽然这并不是你问题的答案(因为其他人已经回答了),但如果你想要对上传文件字段进行一些编辑功能,你可能想做以下几点:

  • 通过打印文件名或URL、点击链接以下载文件或或者作为缩略图展示来显示此字段的当前值。
  • 使用 <input> 标签上传新文件。
  • 添加一个复选框,选中时可以删除当前已上传的文件。请注意,无法上传“空”文件,所以需要像这样清除字段的值。

3
如果我想编辑产品信息(不想更改产品图像),我应该如何将 <input type="file" /> 设置为现有的产品图像? 我可以在 <img /> 标签中显示现有的图像,但提交时没有上传任何文件。 - Partho63
@Partho63 为什么你想要重新上传?如果是因为表单必填字段验证的原因,你可以通过某种方式标记文件输入框为非必填项,如果图片已经上传过了。 - mangatinanda

43

你无法这样做。这是一种安全措施。想象一下,如果有人编写JS代码将文件输入的值设置为某些敏感数据文件,会发生什么?


33

就像这里其他人所说的那样:您不能仅使用JavaScript自动上传任何文件。

但是!如果您可以在代码中访问要发送的信息(即不是C:\passwords.txt),则可以将其上传为blob类型,然后将其视为文件。

服务器最终看到的将与实际设置<input type="file" />的值无法区分。最终的诀窍是使用新的XMLHttpRequest()与服务器开始互动...

function uploadFile (data) {
        // define data and connections
    var blob = new Blob([JSON.stringify(data)]);
    var url = URL.createObjectURL(blob);
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'myForm.php', true);
    
        // define new form
    var formData = new FormData();
    formData.append('someUploadIdentifier', blob, 'someFileName.json');
        
        // action after uploading happens
    xhr.onload = function(e) {
        console.log("File uploading completed!");
    };
    
        // do the uploading
    console.log("File uploading started!");
    xhr.send(formData);
}

    // This data/text below is local to the JS script, so we are allowed to send it!
uploadFile({'hello!':'how are you?'});

那么,你可能会用这个做什么呢? 我用它上传HTML5画布元素作为jpg。这样可以省去用户打开文件输入元素来选择刚刚调整大小、修改等已缓存的图片的麻烦。但它应该适用于任何文件类型。


1
这正是关键所在:您不尝试操纵“经典”的HTML表单提交(并动态设置输入文件),而是通过JS提交整个表单(包括文本等其他输入字段)。最终,只有一个基于JS的请求(POST),而不是单个“经典”提交。我猜这个帖子的许多读者都是因为这些信息而来的。 - Grimm

11

这个主题很古老,但我认为有人可能需要这个答案!

<input type="file" />
    
    <script>
        // Get a reference to our file input
        const fileInput = document.querySelector('input[type="file"]');
    
        // Create a new File object
        const myFile = new File(['Hello World!'], 'myFile.txt', {
            type: 'text/plain',
            lastModified: new Date(),
        });
    
        // Now let's create a DataTransfer to get a FileList
        const dataTransfer = new DataTransfer();
        dataTransfer.items.add(myFile);
        fileInput.files = dataTransfer.files;
    </script>

嗨,我需要这个。谢谢你发布这个。你知道为什么在放置输入的<form>标签本身上没有触发onchange监听器吗? - Lazar Nikolic
fileInput[0].files = dataTransfer.files; 在我的情况下成功运行。 - Tomás Gomez Pizarro
1
@TomásGomezPizarro 你可能在使用 querySelectorAll 或者 jquery,而非querySelector。上述代码可以原封不动地工作。 - Dogoku
1
@LazarNikolic 这对所有输入都是正确的:当以编程方式设置值时,它们不会触发任何事件。如果您想要,可以自己触发事件 input.dispatchEvent(new Event('change', { bubbles: true }) - Dogoku

9
您需要创建一个 DataTransfer 对象并设置输入元素的 .files 属性。
const dataTransfer = new DataTransfer();
dataTransfer.items.add(myFile);//your file(s) reference(s)
document.getElementById('input_field').files = dataTransfer.files;

它是否可以在不使用服务器的情况下与本地文件一起使用?例如,如果我在** MylLocalComputer / MyApplicationPath 上有一个应用程序(html + js),并且在 MyApplicationPath / MySubdir / 中有一个名为 Myfile.txt **的文件,如果我通过javascript字符串将路径传递给Myfile.txt,类似于myFile =“MySubdir / Myfile.txt”,是否可能将文件内容存储到变量中?上面的问题在https://stackoverflow.com/questions/73196322/pass-a-file-of-a-database-as-parameter-to-be-opened-with-a-html-viewer中更好地解释了。 - willy wonka
myFile是另一个<input type="file">值的引用。您需要找出如何在没有输入的情况下创建此引用。 - Guilherme Simão Couto
在我的情况下,我希望用户可以分批选择文件(例如,多次拖放),但要跟踪所有选择并在用户单击“提交”后一次性上传它们。这个答案在这种情况下对我非常有效!谢谢 :) - abbm

-5

在 HTML 中定义:

<input type="hidden" name="image" id="image"/>

在JS中:

ajax.jsonRpc("/consulta/dni", 'call', {'document_number': document_number})
    .then(function (data) {
        if (data.error){
            ...;
        }
        else {
            $('#image').val(data.image);
        }
    })

之后:

<input type="hidden" name="image" id="image" value="/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8U..."/>
<button type="submit">Submit</button>

1
看起来你正在使用ajax调用上传HTML元素的值。这与设置“input type =” file“”元素的值非常不同。 - HoldOffHunger

-15
其实我们可以做到。 我们可以使用C#中的WebBrowser控件和FormToMultipartPostData库来设置文件值的默认值。我们需要下载并将此库包含在我们的项目中。WebBrowser使用户能够在表单内导航网页。 一旦网页加载完成,webBrowser1_DocumentCompleted中的脚本将被执行。 因此,
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
       FormToMultipartPostData postData = 
            new FormToMultipartPostData(webBrowser1, form);
        postData.SetFile("fileField", @"C:\windows\win.ini");
        postData.Submit();
    }

请参考以下链接进行下载和完整参考。

https://www.codeproject.com/Articles/28917/Setting-a-file-to-upload-inside-the-WebBrowser-com


8
这是要翻译成中文的内容:这是用什么语言写的?不是 JavaScript。 - ProgrammingLlama
看起来像是C#。 - schizoid04

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接