jquery 如何从URL或服务器上的文件(而不是文件输入)向FormData()追加文件

gcuhipw9  于 2023-01-12  发布在  jQuery
关注(0)|答案(2)|浏览(119)

我正在编写一段使用Stripe Connect API的代码,用户可以通过jQuery将input type="file"中的可视化对象发送到 AJAX 调用,方法如下:

var form_file = new FormData();
form_file.append('file', document.querySelector('input#file_to_send').files[0]);

当用户提交表单时,我通过PHP将视觉效果复制到服务器上的一个文件夹中,并将其名称保存在一个会话变量中。如果表单中有错误或缺失,用户将返回到同一页面,在该页面中,视觉效果显示在input type="file"元素下的img元素中,因此用户知道他们的视觉效果已被考虑在内。
在那之后,我需要再次在 AJAX 调用中发送文件......除了这一次,文件不能再从input type="file"中选择,我唯一可以访问的源将是从JavaScript中的img元素中获取它的名称。
现在,如果我这样做:

var form_file = new FormData();
form_file.append('file', $('img#visual').attr('src'));

并通过相同的 AJAX 调用发送此消息:

$.ajax({
    url: 'https://uploads.stripe.com/v1/files',
    type: 'POST',
    processData: false,
    contentType: false,
    headers: {'Authorization': 'Bearer xxxxxxxxxxxxxxxxx' },
    data: form_file
}).fail(function(e) {
    console.log('fail: ' + e);
}).done(function(e) {
    console.log('file uploaded: ' + e.id);
});

我的问题,你猜对了,是:是否有方法/应该如何发送不是来自input元素的文件作为源,而是来自img元素的已定义路径?

bf1o4zei

bf1o4zei1#

我又读了一遍你的问题。如果我理解正确的话,你需要发送一个跨域AJAX请求到www.example.com,所以你不是在控制服务器端的PHP代码,对吗?stripe.com, so you are not controlling the PHP code on the server side, right?

    • 简短回答:**

最简单的方法是用Javascript而不是PHP进行表单检查,这样就不需要返回并"丢失"所选的输入文件。
...*但是*如果您确实需要/想要仅使用其URL发送跨域文件
则需要将数据URI转换为文件,然后附加到FormData
1/获取图像base64值

function toDataUrl(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
        var reader = new FileReader();
        reader.onloadend = function() {
            callback(reader.result);
        }
        reader.readAsDataURL(xhr.response);
    };
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();
}

2/将base64图像转换为Blob:

function DataURIToBlob(dataURI: string) {
    const splitDataURI = dataURI.split(',')
    const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
    const mimeString = splitDataURI[0].split(':')[1].split(';')[0]

    const ia = new Uint8Array(byteString.length)
    for (let i = 0; i < byteString.length; i++)
       ia[i] = byteString.charCodeAt(i)

    return new Blob([ia], {
       type: mimeString
    })
 }

3/向您发送带有FormData的Blob:

const file = DataURIToBlob(imgBase64)
const formData = new FormData();
formData.append('upload', file, 'image.jpg')

资料来源:

通过使用Fetch API直接获取图像Blob,可以加快第1阶段和第2阶段的速度。
(警告:与IE不兼容)
来源:How to get a File() or Blob() from an URL in javascript?

vuv7lop3

vuv7lop32#

我能够实现我想要的!下面是我最终得到的代码:

var visual_source = 'upload/file-source.png';
var visual_ext = visual_source.split('.').pop();
var visual = await fetch(visual_source);
console.log(visual);
var visual_as_blob = await visual.blob();
console.log(visual_as_blob);
var visual_as_file = new File([visual_as_blob], 'file-name-renamed.' + visual_ext, { lastModified: new Date().getTime(), type: visual_as_blob.type });
console.log(visual_as_file);
form_file.append('file', visual_as_file);

如果有人需要这段代码并想一步一步地看到所发生的事情的结果,我在每一步都添加了console.log()。

  • 我们从一个给定的URL获取文件(这里是服务器上“upload”文件夹中的一个文件)
  • 我们将获取的数据设置为blob
  • 我们将blob转换为文件
  • 然后,我们可以将该文件追加()到FormData()元素

之后,它可以通过 AJAX 发送到API。

相关问题