通过 chrome 扩展上传文件作为表单数据 [英] Upload File as a Form Data through chrome extension
问题描述
我正在通过 chrome 扩展上传一个文件作为表单数据,我的代码如下.这里的问题是文件浏览窗口只打开了一秒钟,然后就消失了.
该问题仅在 Mac OS 中出现.
I am uploading a file through chrome extension as a form data and my code follows below. The problem here is that the file browsing window opens for just a second and then disappears.
The issue appears in Mac OS only.
manifest.json:
"background": {
"scripts": ["jszip.js", "background.js"]
},
background.js:
chrome.runtime.onMessage.addListener(function (msg) {
if (msg.action === 'browse')
{
var myForm=document.createElement("FORM");
var myFile=document.createElement("INPUT");
myFile.type="file";
myFile.id="selectFile";
//myFile.onclick="openDialog()";
myForm.appendChild(myFile);
var myButton=document.createElement("INPUT");
myButton.name="submit";
myButton.type="submit";
myButton.value="Submit";
myForm.appendChild(myButton);
document.body.appendChild(myForm);
}
});
popup.js:
window.onload = function () {
chrome.runtime.sendMessage({
action: 'browse'
});
}
推荐答案
一个小背景故事":
您想让用户从您的弹出窗口中选择并上传文件.但是在 OSX 中,只要文件选择器对话框打开,弹出窗口就会失去焦点并关闭,从而导致其 JS 上下文也被破坏.因此,对话框会立即打开和关闭.
A little "background story":
You want to let the user choose and upload a file from your popup. But in OSX, as soon as the file-chooser dialog opens, the popup loses focus and closes, causing its JS context to get destroyed as well. Thus, the dialog opens and closes immediately.
这是一个已知错误 在 MAC 上使用了很长时间.
This is a known bug on MAC for quite some time.
您可以将对话框打开逻辑移动到后台页面,不受失去焦点的影响.从弹出窗口中,您可以向后台页面发送消息,请求启动浏览和上传过程(参见下面的示例代码).
You can move the dialog opening logic to the background-page, which is not affected by loss of focus. From the popup, you can send a message to the background-page, requesting to initiate the browse-and-upload process (see sample code below).
manifest.json
{
...
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"browser_action": {
"default_title": "Test Extension",
// "default_icon": {
// "19": "img/icon19.png",
// "38": "img/icon38.png"
// },
"default_popup": "popup.html"
},
"permissions": [
"https://www.example.com/uploads"
// The above permission is needed for cross-domain XHR
]
}
popup.html
...
<script src="popup.js"></script>
</head>
<body>
<input type="button" id="button" value="Browse and Upload" />
...
popup.js
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('button').addEventListener('click', function () {
chrome.runtime.sendMessage({ action: 'browseAndUpload' });
window.close();
});
});
background.js
var uploadUrl = 'https://www.example.com/uploads';
/* Creates an `input[type="file]` */
var fileChooser = document.createElement('input');
fileChooser.type = 'file';
fileChooser.addEventListener('change', function () {
var file = fileChooser.files[0];
var formData = new FormData();
formData.append(file.name, file);
var xhr = new XMLHttpRequest();
xhr.open('POST', uploadUrl, true);
xhr.addEventListener('readystatechange', function (evt) {
console.log('ReadyState: ' + xhr.readyState,
'Status: ' + xhr.status);
});
xhr.send(formData);
form.reset(); // <-- Resets the input so we do get a `change` event,
// even if the user chooses the same file
});
/* Wrap it in a form for resetting */
var form = document.createElement('form');
form.appendChild(fileChooser);
/* Listen for messages from popup */
chrome.runtime.onMessage.addListener(function (msg) {
if (msg.action === 'browseAndUpload') {
fileChooser.click();
}
});
<小时>
<子>注意:
为安全起见,Chrome 将fileChooser.click()
仅在用户交互的结果下执行.
在上面的例子中,用户点击弹出窗口中的按钮,它会向后台页面发送一条消息,该消息调用fileChooser.click();
.如果您尝试以编程方式调用它,它将不起作用.(例如,在文档加载时调用它不会产生任何影响.)
Heads up:
As a security precaution, Chrome will execute fileChooser.click()
only if it is a result of user interaction.
In the above example, the user clicks the button in the popup, which sends a message to the background-page, which calls fileChooser.click();
. If you try to call it programmatically it won't work. (E.g. calling it on document load won't have any effect.)
这篇关于通过 chrome 扩展上传文件作为表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!