如何将文件从 URL 或服务器上的文件而不是文件输入附加到 FormData()
How to append a file to a FormData() from a URL or file on server rather than a file input
我正在使用 Stripe Connect API 编写一段代码,用户可以在其中将视觉效果从 input type="file"
发送到 AJAX 通过 jQuery 调用,这样:
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);
});
我的问题,您猜对了,是:有没有一种方法 to/how 我应该发送一个文件,而不是从 input
元素作为源,而是从img
元素?
我又看了一遍你的问题。如果我理解正确的话你需要发送跨域AJAX请求到stripe.com,这样你就不会控制服务器上的PHP代码边对吧?
简答:
最简单的方法是在 Javascript 而不是 PHP 中进行表单检查,这样您就不需要返回并“丢失”所选的输入文件。
...但是如果你真的need/want到发送跨域文件使用只有它的 URL,
然后您需要将 Data URI 转换为 File 然后附加到 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')
来源:
- CONVERT Image url to Base64
- https://pretagteam.com/question/how-to-append-an-image-from-url-to-a-formdata-javascript
- https://www.geeksforgeeks.org/how-to-convert-data-uri-to-file-then-append-to-formdata/
编辑:
您可以通过使用 Fetch API 直接获取图像 Blob 来加快阶段 1 和阶段 2。
(警告:与 IE 不兼容)
来源:
谢谢@e-telier!将您的代码示例与您建议的链接上的内容相结合后,我能够实现我想要的!这是我最终得到的代码:
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 中获取文件(这里是服务器上“上传”文件夹中的一个文件)
- 我们将获取的数据设置为blob
- 我们将 blob 转换为文件
- 然后我们可以将文件追加到 FormData() 元素
之后,可以通过ajax发送到StripeAPI。
再次感谢您的帮助!! :))
我正在使用 Stripe Connect API 编写一段代码,用户可以在其中将视觉效果从 input type="file"
发送到 AJAX 通过 jQuery 调用,这样:
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);
});
我的问题,您猜对了,是:有没有一种方法 to/how 我应该发送一个文件,而不是从 input
元素作为源,而是从img
元素?
我又看了一遍你的问题。如果我理解正确的话你需要发送跨域AJAX请求到stripe.com,这样你就不会控制服务器上的PHP代码边对吧?
简答:
最简单的方法是在 Javascript 而不是 PHP 中进行表单检查,这样您就不需要返回并“丢失”所选的输入文件。
...但是如果你真的need/want到发送跨域文件使用只有它的 URL,
然后您需要将 Data URI 转换为 File 然后附加到 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')
来源:
- CONVERT Image url to Base64
- https://pretagteam.com/question/how-to-append-an-image-from-url-to-a-formdata-javascript
- https://www.geeksforgeeks.org/how-to-convert-data-uri-to-file-then-append-to-formdata/
编辑:
您可以通过使用 Fetch API 直接获取图像 Blob 来加快阶段 1 和阶段 2。
(警告:与 IE 不兼容)
来源:
谢谢@e-telier!将您的代码示例与您建议的链接上的内容相结合后,我能够实现我想要的!这是我最终得到的代码:
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 中获取文件(这里是服务器上“上传”文件夹中的一个文件)
- 我们将获取的数据设置为blob
- 我们将 blob 转换为文件
- 然后我们可以将文件追加到 FormData() 元素
之后,可以通过ajax发送到StripeAPI。
再次感谢您的帮助!! :))