【问题标题】:Chrome Extension Development - POST to new tabChrome 扩展开发 - 发布到新标签
【发布时间】:2011-11-15 06:40:15
【问题描述】:

是否有一种简单的解决方案可以将动态聚合的数据发布到新标签中?

chrome.tabs.create 没有“POST”选项。通常我会使用

chrome.browserAction.onClicked.addListener(function (t) {
  chrome.tabs.create(
  {
    "url" : "http://super.url",
    "method" : "POST" // oops.. no option.
  });
});

【问题讨论】:

  • 嗯,我能想到的唯一解决方案是将您的动态数据发送到后台文件,创建一个包含表单的新选项卡。使用后台文件的内容使用您的表单填写表单,然后提交表单。没有别的我能想到的。
  • 听起来是个好计划。您是否知道任何指向您提到的确切解决方案的资源?首先 - 从“父”选项卡操作新选项卡内容。
  • 这需要一些时间来学习,好吗?首先在 Google 的文档中阅读有关 content scripts 的信息。然后阅读message passing。在您理解了所有这些之后,从脚本向后台发送消息以及向不同选项卡的脚本发送消息将相当简单。不过,我可能对此有误,因为可能存在一种方式,通过这种方式 2 个选项卡可以在没有这种麻烦的情况下进行通信。只要问我是否让你感到困惑。

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

您可以简单地将这两种技术结合起来:

  1. 您可以通过在地址栏或<a> 标签的href 值中添加javascript: 前缀来执行JavaScript 命令。
  2. 只有使用 JavaScript,您才能创建一个表单元素并用您的数据填充它,然后发布它。
function fakePost() {
    var form = document.createElement("form");
    
    // Create a POST dump at ptsv2.com and change the code
    form.setAttribute("action", "http://ptsv2.com/t/dcgex-1614815819/post");
    form.setAttribute("method", "post");

    var params = { userId: 2, action: "delete" };
    for(var key in params) {
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", params[key]);
        form.appendChild(hiddenField);
    }

    // Appending the form might not be necessary
    document.body.appendChild(form);

    form.submit();
};

const 
    source = fakePost.toString().replace(/(\n|\t)/gm,'').replace(/\s\s/gm,' '),
    url = `javascript:${source}; fakePost();`;

chrome.browserAction.onClicked.addListener(() => chrome.tabs.create({ url }));

当然,这只是一个肮脏的技巧。如果您需要更详细的信息,可以使用XHR Object 或@Xan 的答案。

【讨论】:

  • 当心!此答案不应用于敏感的表单数据,因为网页可以拦截和操纵以这种方式插入的表单数据。
  • @RobW 这只是一个示例,用于演示目的......不要认真,对于那些复制粘贴开发者来说,他们应该承担后果。
【解决方案2】:

cvsguimaraes 答案中的代码适用于短数据字符串,可以放入 URL。 正如this question 所证明的那样,情况并非总是如此。

Kenny Evitt 的回答暗示了解决方案。我为这个问题做了一个实现,并花时间来概括它。我在这里介绍它。

这个想法是打开一个与扩展程序捆绑在一起的页面 (post.html),通过消息传递给它所需的信息,然后从该页面执行 POST。

post.html

<html>
  <head>
    <title>Redirecting...</title>
  </head>
  <body>
    <h1>Redirecting...</h1>
    <!-- Decorate as you wish, this is a page that redirects to a final one -->
    <script src="post.js"></script>
  </body>
</html>

post.js

var onMessageHandler = function(message){
  // Ensure it is run only once, as we will try to message twice
  chrome.runtime.onMessage.removeListener(onMessageHandler);

  // code from https://stackoverflow.com/a/7404033/934239
  var form = document.createElement("form");
  form.setAttribute("method", "post");
  form.setAttribute("action", message.url);
  for(var key in message.data) {
    var hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", key);
    hiddenField.setAttribute("value", message.data[key]);
    form.appendChild(hiddenField);
  }
  document.body.appendChild(form);
  form.submit();
}

chrome.runtime.onMessage.addListener(onMessageHandler);

background.js(或扩展内的其他非内容脚本)

function postData(url, data) {
  chrome.tabs.create(
    { url: chrome.runtime.getURL("post.html") },
    function(tab) {
      var handler = function(tabId, changeInfo) {
        if(tabId === tab.id && changeInfo.status === "complete"){
          chrome.tabs.onUpdated.removeListener(handler);
          chrome.tabs.sendMessage(tabId, {url: url, data: data});
        }
      }

      // in case we're faster than page load (usually):
      chrome.tabs.onUpdated.addListener(handler);
      // just in case we're too late with the listener:
      chrome.tabs.sendMessage(tab.id, {url: url, data: data});
    }
  );  
}

// Usage:
postData("http://httpbin.org/post", {"hello": "world", "lorem": "ipsum"});

注意双重消息:使用chrome.tabs.create 回调,我们不能确定监听器是否准备就绪,也不能确定它还没有完成加载(尽管在我的测试中,它总是在加载)。但安全总比后悔好。

【讨论】:

  • 请告诉我 post.js 是内容脚本还是弹出脚本?
  • @senty 两者都不是。它是扩展页面中的脚本,不是弹出窗口。
  • 我有点困惑。如果我在弹出窗口中添加了.js 文件,我是否应该使用您的post.js 并在函数中调用它,并像您在此处显示的那样设置background.js?或者这是完全不同的方法?
【解决方案3】:

来自@Amman Cheval 的问题:

[发送]您的动态数据到后台文件,创建一个包含表单的新选项卡。使用后台文件的内容使用你的表单填写表单,然后提交表单。

首先阅读 Google 文档中的内容脚本。然后阅读消息传递。在您了解了所有这些之后,从脚本向后台发送消息以及向不同选项卡的脚本发送消息将相当简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2012-03-23
    • 2012-03-30
    • 1970-01-01
    相关资源
    最近更新 更多