javascript Chrome 扩展开发 - POST 到新标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7387217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:56:51  来源:igfitidea点击:

Chrome Extension Development - POST to new tab

javascriptgoogle-chromegoogle-chrome-extension

提问by Pono

Is there an easy solution to POST dynamically aggregated data into a new tab?

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

chrome.tabs.createdoes not have a 'POST' option. Normally I would use

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

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

回答by 2grit

You can simply combine these two techniques:

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

  1. You may execute JavaScript commands by adding javascript:prefix at your address bar or in hrefvalues of <a>tags.
  2. Only with JavaScript, you can create a form element and fill it with your data then POST it.
  1. 您可以通过javascript:在地址栏或标签href值中添加前缀来执行 JavaScript 命令<a>
  2. 只有使用 JavaScript,你才能创建一个表单元素并用你的数据填充它然后发布它。

.

.

function fakePost() {   
    var form = document.createElement("form");
    form.setAttribute("method", "post");
    form.setAttribute("action", "http://cvsguimaraes.altervista.org/fiddles/postcheck.php");
    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);
    }
    document.body.appendChild(form); // Not sure if this step is necessary
    form.submit();
};
//minify function
fakePostCode = fakePost.toString().replace(/(\n|\t)/gm,'');

chrome.browserAction.onClicked.addListener(function (t) {
  chrome.tabs.create({"url" : "javascript:"+fakePostCode+"; fakePost();"});
});

Of course, that's just a dirty hack. If you need something better you can use a XHR Objector elaborate something more like @Xan's answer below.

当然,这只是一个肮脏的黑客。如果您需要更好的东西,您可以使用XHR 对象或详细说明更像下面@Xan 的答案。

回答by Xan

The code in cvsguimaraes' answer works for short data strings, that can fit into a URL. As evidenced by this question, it's not always the case.

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

Kenny Evitt's answer hints at the solution. I made an implementation for that question, and took time to generalize it. I present it here.

肯尼·埃维特 (Kenny Evitt) 的回答暗示了解决方案。我为那个问题做了一个实现,并花时间概括它。我在这里介绍。

The idea is to open a page bundled with the extension (post.html), supply it with required information via messaging, and perform the POST from that page.

这个想法是打开一个与扩展 (post.html) 捆绑在一起的页面,通过消息为其提供所需的信息,然后从该页面执行 POST。

post.html

后.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

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(or other non-content script inside the extension)

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

Note the double messaging: with chrome.tabs.createcallback we can't be sure that the listener is ready, nor can we be sure it's not done loading yet (though in my testing, it's always still loading). But better safe than sorry.

请注意双重消息传递:使用chrome.tabs.create回调我们不能确定侦听器已准备好,也不能确定它尚未完成加载(尽管在我的测试中,它始终仍在加载)。但安全总比后悔好。

回答by Kenny Evitt

From @Amman Cheval's comments on the question:

来自@Amman Cheval 对这个问题的评论:

[send] your dynamic data to the background file, creating a new tab which includes a form. Fill up the form using your form using the content using the background file, and then submit the form.

Read up about content scripts on Google's docs first. Then read up on message passing. After you've understood all of that, it'd be fairly simple to send a message from the script, to the background, and to the script of a different tab.

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

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