一点“背景故事”:
您想让用户从弹出窗口中选择并上传文件。但是在OSX中,一旦打开文件选择器对话框,弹出窗口便失去焦点并关闭,从而导致其JS上下文也被破坏。因此,对话框打开并立即关闭。
这是MAC上的一个
已知错误
,已有一段时间了。
解决方案:
您可以将对话框打开逻辑移动到背景页面,而不受焦点丢失的影响。您可以从弹出窗口向后台页面发送一条消息,请求启动浏览和上传过程(请参见下面的示例代码)。
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';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});var form = document.createElement('form');form.appendChild(fileChooser);chrome.runtime.onMessage.addListener(function (msg) { if (msg.action === 'browseAndUpload') { fileChooser.click(); }});注意 : 为了安全起见,
fileChooser.click()只有 在用户互动的情况下,Chrome才会执行。
在上面的示例中,用户单击弹出窗口中的按钮,该按钮将消息发送到调用的后台页面
fileChooser.click();。如果您尝试以编程方式调用它,则将无法使用。(例如,在文档加载时调用它不会有任何效果。)



