通过Chrome扩展将文件上传为表单数据 [英] Upload File as a Form Data through chrome extension

查看:144
本文介绍了通过Chrome扩展将文件上传为表单数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过Chrome扩展程序上传文件作为表单数据,我的代码如下所示。这里的问题是文件浏览窗口打开了一秒钟后就消失了。

这个问题只出现在Mac OS上。



manifest.json :

 background:{
脚本:[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上下文也被破坏。因此,对话框会立即打开并关闭。



这是 已知bug 在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
},

权限:[
https:// www.example.com/uploads
//上述许可需要跨域XHR
]
}

popup.html

  ... 
< script src =popup.js>< / script>
< / head>
< body>
< input type =buttonid =buttonvalue =浏览并上传/>
...

popup.js



$ p $ document.addEventListener('DOMContentLoaded',function(){
document.getElementById('button')。addEventListener('click' ,函数(){
chrome.runtime.sendMessage({action:'browseAndUpload'});
window.close();
});
});

background.js

  var uploadUrl ='https://www.example.com/uploads'; 
$ b $ *创建一个`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',函数(evt){
console.log('ReadyState:'+ xhr.readyState,
'状态:'+ xhr.status);
});

xhr.send(formData);
form.reset(); //< - 重置输入,所以我们得到一个`change`事件,
//即使用户选择相同的文件
});

/ *将它包装在表单中以便重置* /
var form = document.createElement('form');
form.appendChild(fileChooser);

/ *收听讯息popup * /
chrome.runtime.onMessage.addListener(function(msg){
if(msg.action ==='browseAndUpload'){
fileChooser.click();
}
});







请注意:
为安全起见,Chrome会执行 fileChooser.click()
是用户交互的结果。

在上面的例子中,用户点击弹出框中的按钮,该按钮向后台页面发送消息,该消息调用 fileChooser.click( ); 。如果您尝试以编程方式调用它,它将无法工作。 (例如,在文档加载时调用它不会产生任何影响。)


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'
  });
}

解决方案

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.

This is a known bug on MAC for quite some time.


The solution:

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();
    }
});


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆