书签以将页面源提交到表单 [英] Bookmarklet to submit page source to form

查看:73
本文介绍了书签以将页面源提交到表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用小书签将当前页面源发送到服务器功能,然后服务器功能对其进行处理(存储它,不需要将任何信息返回给用户).

I'm using a bookmarklet to send the current page source to a server function which then processes it (stores it, no information needs to be returned to the user).

警告:丑陋的Java脚本,这不是我通常需要使用的语言.

Warning: ugly Javascript ahead, it's not a language I normally need to use.

这是小书签,打印精美,便于阅读:

Here's the bookmarklet, pretty-printed for ease of reading:

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接收头部和身体部分.

This basically works, "do.php" receives the head and body sections in form variable h.

但是,似乎每个页面只能使用一次.如果在同一页面上两次按小书签,则不会发生任何事情.重新加载页面后,它可以再次工作.有什么我应该重设的东西吗? (当然,运行一次就足够了,但是第二次按下时可以向用户提供一些反馈是很好的.)

However, it only seems to work once for each page. If the bookmarklet is pressed twice for the same page, nothing happens. When the page is reloaded, it works again. Is there something I should be resetting? (running once is enough of course, but it would be nice to give some feedback to the user the second time it is pressed).

其次,这会弹出一个新的选项卡/窗口.我可以通过让do.php返回一些javascript关闭窗口来解决此问题(注意:这只是出于测试目的,而不是实际代码):

Secondly, this pops up a new tab/window. I can work around this by having do.php return some javascript to close the window (note: this is just for testing purposes, not real code):

<?php
$page = $_REQUEST['h'];
file_put_contents('/tmp/work.txt', $page);
echo '<script type="text/javascript">window.close();</script>"';
?>

丑陋.快速刷新新标签页,然后消失了.有没有更好的方法?一条成功"消息会很好,但是我看不到如何合并它.

Ugly. Quick flash of the new tab, then it's gone. Is there a better approach? A "success" message would be nice, but I can't see how to incorporate that.

推荐答案

首先,您不想将表单附加到文档主体,因为表单的HTML随后将包含在后续的POST请求中,因此您可能不想要,所以删除此行:

First of all, you don't want to append the form to the document's body, because the form's HTML will then be included in subsequent POST requests, and you probably don't want that, so remove this line:

document.body.appendChild(d);

第二,看来通过浏览器向同一URL的多个提交被浏览器阻止了(无论如何,对于Google Chrome而言).通过按钮上的onclick处理程序运行的完全相同的代码每次都起作用.解决方案是向每个请求添加一个额外的随机参数,如下所示:

Secondly, it appears that multiple submissions to the same URL via bookmarklets are blocked by the browser (in Google Chrome's case anyway). The exact same code, run via an onclick handler on a button works every time. The solution is to add an additional, random parameter to each request, like this:

d.action = "http://example.com/do.php?nocache=" + Math.random();

我不知道这是安全还是缓存问题,但是此修复程序有效.

I don't know if this a security or a caching issue, but this fix works.

现在,进入新窗口.这是因为您将target = "_blank"属性添加到了表单.当然,如果您不这样做,那么表单将在当前窗口/选项卡中提交,并且您可能不希望用户离开该页面.尝试尝试的第一个想法是使用iframe,将其附加到表单,将iframe附加到文档,提交表单,然后删除iframe.当然,您将需要一种机制来知道表单何时完成提交,这可能会使您进入跨域"限制范围,但是值得一试.您还可以研究跨域AJAX请求和JSONP.

Now, on to the new window. This is because you added the target = "_blank" attribute to the form. Of course, if you don't do that, the form submits in the current window / tab, and you probably don't want the user to leave the page. The first think to try would be using an iframe, appending the form to it, appending the iframe to the document, submitting the form, and then removing the iframe. Of course, you would need a mechanism to know when the form has finished submitting, which would probably land you in "cross-domain" restrictions land, but it's worth a try. You could also look into cross-domain AJAX requests, and JSONP.

更新

我想我明白了!我认为提交完成后不需要目的地页面来通知您,您可以依靠iframe的load事件.我已经在Chrome浏览器中对其进行了测试,并且可以完美运行,请也测试其他浏览器.查看代码注释:

I think I've got it! I figured that you don't need the destination page to notify you when the submit is done, you can rely on the iframe's load event. I've tested this in Chrome and it works perfectly, please test other browsers too. See the code comments:

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

这篇关于书签以将页面源提交到表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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