我正在使用书签将当前页面源发送到服务器函数,然后处理它(存储它,不需要将信息返回给用户)。
警告:丑陋的Javascript未来,它不是我通常需要使用的语言。
这是小书签,非常易于阅读:
javascript: (function () {
var h = document.documentElement.innerHTML;
function c(a, b) {
var c = document.createElement("textarea");
c.name = a;
c.value = b;
d.appendChild(c)
}(document), d = document.createElement("form");
d.method = "POST";
d.action = "http://example.com/do.php";
d.enctype = "multipart/form-data";
d.target = "_blank";
c("h", h);
c("u", "1234");
document.body.appendChild(d);
d.submit();
})();
这基本上有效,“do.php”以形式变量h接收头部和身体部分。
但是,它似乎只为每个页面工作一次。如果为同一页面按两次书签,则不会发生任何事情。重新加载页面时,它会再次运行。有什么我应该重置的吗? (运行一次就足够了,但是第二次按下时给用户提供一些反馈会很好。)
其次,这会弹出一个新的标签/窗口。我可以通过让do.php返回一些javascript关闭窗口来解决这个问题(注意:这仅用于测试目的,而不是真正的代码):
<?php
$page = $_REQUEST['h'];
file_put_contents('/tmp/work.txt', $page);
echo '<script type="text/javascript">window.close();</script>"';
?>
难看。快速刷新新标签,然后它就消失了。有更好的方法吗?一个“成功”的消息会很好,但我看不出如何融入它。
答案 0 :(得分:2)
首先,您不希望将表单附加到文档的正文中,因为表单的HTML随后将包含在后续的POST请求中,您可能不希望这样,所以删除此行:
document.body.appendChild(d);
其次,浏览器会阻止通过bookmarklet对同一网址进行多次提交(无论如何都是谷歌Chrome的情况)。通过按钮上的onclick
处理程序运行的完全相同的代码每次都有效。解决方案是为每个请求添加一个额外的随机参数,如下所示:
d.action = "http://example.com/do.php?nocache=" + Math.random();
我不知道这是一个安全问题还是缓存问题,但是此解决方案有效。
现在,进入新窗口。这是因为您在表单中添加了target = "_blank"
属性。当然,如果您不这样做,表单会在当前窗口/选项卡中提交,您可能不希望用户离开页面。首先考虑尝试使用iframe,将表单附加到其中,将iframe附加到文档,提交表单,然后删除iframe。当然,您需要一种机制来了解表单何时完成提交,这可能会让您陷入“跨域”限制的土地,但值得一试。您还可以查看跨域AJAX请求和JSONP。
<强>更新强>
我想我已经拥有了!我认为您在提交完成后不需要目标页面通知您,您可以依赖iframe的load
事件。我在Chrome中对此进行了测试,效果很好,请测试其他浏览器。请参阅代码注释:
(function () {
var html = document.documentElement.innerHTML;
/**
* the iframe's onload event is triggered twice: once when appending it to the document,
* and once when the form finishes submitting and the new URL is loaded
*/
var loaded = 0;
var iframe = document.createElement('iframe');
// unique name, to make sure we don't create any conflicts with other elements on the page
iframe.name = 'bookmarklet-' + Math.floor((Math.random() * 10000) + 1);
iframe.style.display = 'none';
iframe.onload = function () {
// remove the iframe from the document on the second firing of the onload event
if (++loaded == 1) {
return;
}
// you can also alert('Done!') here :)
document.body.removeChild(iframe);
};
var form = document.createElement('form');
form.method = "POST";
form.action = "http://requestb.in/sbnc0lsb?nocache=" + Math.random();
form.target = iframe.name;
var textarea = document.createElement('textarea');
textarea.name = 'source';
textarea.value = html;
form.appendChild(textarea);
iframe.appendChild(form);
document.body.appendChild(iframe);
form.submit();
})();