【问题标题】:Upload a File in a Google Chrome Extension在 Google Chrome 扩展程序中上传文件
【发布时间】:2011-05-04 20:53:10
【问题描述】:

我正在为 Chrome 编写扩展程序,我需要从用户当前所在的页面上传文件到我的服务器进行处理,但我不知道如何上传文件。我考虑只是将链接传递给服务器并让服务器下载文件,但是如果站点需要身份验证,这将不起作用。是否可以通过 Chrome 扩展程序将文件上传到我的服务器?

【问题讨论】:

    标签: google-chrome-extension upload


    【解决方案1】:

    我最近开发了一个 Chrome 扩展程序,它可以从页面中检索内容,并将其发送到服务器。

    使用了以下方法:

    1. 文件下载:例如,获取 <img> 元素的 src 属性。
    2. 从缓存中获取文件 - 使用后台页面中的XMLHttpRequest
    3. 在后台页面中使用Web Worker 来处理上传。

    旁注,要获取图像的校验和,可以使用Crypto-JS: MD5。示例(其中xhrXMLHttpRequest 对象,其中responseType 设置为arraybuffer,请参阅Worker 演示):

    var md5sum = Crypto.MD5( new Uint8Array(xhr.response) );
    

    完整示例

    Content script

    // Example: Grab the first <img> from the document if it exists.
    var img = document.images[0];
    if (img) {
        // Send the target of the image:
        chrome.runtime.sendMessage({method: 'postUrl', url: img.src});
    }
    

    后台脚本(带 Worker)

    chrome.runtime.onMessage.addListener(function(request) {
        if (request.method == 'postUrl') {
            var worker = new Worker('worker.js');
            worker.postMessage(request.url);
        }
    });
    

    网络工作者

    // Define the FormData object for the Web worker:
    importScripts('xhr2-FormData.js')
    
    // Note: In a Web worker, the global object is called "self" instead of "window"
    self.onmessage = function(event) {
        var resourceUrl = event.data;   // From the background page
        var xhr = new XMLHttpRequest();
        xhr.open('GET', resourceUrl, true);
    
        // Response type arraybuffer - XMLHttpRequest 2
        xhr.responseType = 'arraybuffer';
        xhr.onload = function(e) {
            if (xhr.status == 200) {
                nextStep(xhr.response);
            }
        };
        xhr.send();
    };
    function nextStep(arrayBuffer) {
        var xhr = new XMLHttpRequest();
        // Using FormData polyfill for Web workers!
        var fd = new FormData();
        fd.append('server-method', 'upload');
    
        // The native FormData.append method ONLY takes Blobs, Files or strings
        // The FormData for Web workers polyfill can also deal with array buffers
        fd.append('file', arrayBuffer);
    
        xhr.open('POST', 'http://YOUR.DOMAIN.HERE/posturl.php', true);
    
        // Transmit the form to the server
        xhr.send(fd);
    };
    

    FormData 网络工作者 POLYFILL

    Web workers 本身不支持FormData 对象,用于传输multipart/form-data 表单。这就是为什么我为它写了一个polyfill。此代码必须包含在 Web Worker 中,使用 importScripts('xhr2-FormData.js')

    polyfill 的源代码在https://gist.github.com/Rob--W/8b5adedd84c0d36aba64

    清单文件:

    {
      "name": "Rob W - Demo: Scraping images and posting data",
      "version": "1.0",
      "manifest_version": 2,
      "content_scripts": [
        {
          "matches": ["http://*/*", "https://*/*"],
          "js": ["contentscript.js"]
        }
       ],
       "background": {
           "scripts": ["background.js"]
       },
       "permissions": ["http://*/*", "https://*/*"]
    }
    

    相关文档

    【讨论】:

    • Rob 这是很棒的东西,感谢您发布如此详细的回复。我注意到在this other thread 中,如果您要发送较大的文件,您建议不要使用 Web Worker。如果有问题的文件将超过 500kb,您是否仍建议将 XMLHttpRequest 保留在后台进程中(不使用网络工作者)以获得 chrome 扩展?
    • 另外,如何确保 arraybuffer 响应来自缓存而不是发出新请求?
    • @NoR 我建议不要使用 Web Worker,除非你打算做一些昂贵的阻塞 IO,或者做一些 CPU 密集型处理。 XMLHttpRequest 对缓存行为几乎没有控制,但fetch API 提供了一些方法来控制这一点。
    • 我觉得你正在挥动最重要的部分——从页面获取内容(例如图像)。您说“从缓存中获取文件 - 使用后台页面中的 XMLHttpRequest”。但是当您添加“XMLHttpRequest 对缓存行为几乎没有控制”时,就会对此提出质疑。
    • 并添加,对于我的用例,这 非常 很重要,因为可能无法(再次)使用页面中的 URL 获取页面上的内容(由于带宽限制或原件过期)
    【解决方案2】:

    最简单的解决方案似乎是让您的扩展程序将文件的 URI 发送到您的服务器,然后您的服务器端代码会将其从页面下载到服务器并进行处理。

    创建一个服务器端脚本,例如 http://mysite.com/process.php?uri=[file's URI goes here],它将处理给定的文件。使用 AJAX 调用此 URL(更多信息在 http://code.google.com/chrome/extensions/xhr.html )。该脚本将返回处理后的文件,然后您可以在扩展程序中使用该文件。

    【讨论】:

    • 就像我在我的问题中所说的,仅适用于不在登录/付费墙后面的文件。
    • 链接打不开
    【解决方案3】:

    您应该检查以下内容:

    chrome.extension.sendRequest() 和 chrome.extension.onRequest()

    您可以在此处阅读有关它们的更多信息:http://code.google.com/chrome/extensions/messaging.html

    基本上,您将在服务器上设置页面以监视 Chrome 扩展程序,一旦它们连接,您将需要一个 javascript 来为您执行上传任务。

    我还没有对此进行测试,但它可能会让你到达你需要的地方。此外,您可能还想阅读长期连接部分。

    祝你好运

    【讨论】:

    • 我认为您误解了我要完成的任务。该插件将允许用户从任何网站上传文件(比如 PDF)到我的网站进行重新处理。我希望这种情况发生,而用户不必先下载文件,然后将其上传给我。目前,插件会找到所有文档(类型正确)并将它们列在插件的弹出窗口中。我希望用户能够简单地从弹出窗口中选择一个并自动上传。我可能无法控制用户当前导航到的页面/服务器。
    • 好吧,这是有道理的,你说得对,我误解了你的意图。我使用了一个具有类似功能的插件,它会列出您正在查看的站点上的所有 Flash 视频,并允许您将它们上传到另一个站点。那是我的旧笔记本电脑,我已经没有了,我会寻找它,看看是否有什么可以帮助的。
    猜你喜欢
    • 1970-01-01
    • 2014-09-13
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多