历史API,刷新和书签

时间:2012-07-24 19:32:38

标签: javascript refresh history bookmarks pushstate

pushState不会发出请求,只会更改网址并存储新的历史记录条目。考虑到这个概念,刷新或书签是不可能的,因为服务器总是会提出请求。需要服务器端解决方案 经过几个小时的搜索,我找到了一个解决方案,每个调用都必须重定向到index.php,让PHP处理请求。

rewrite ^/(.*)$ /index.php?page=$1 last

我不知道该文件应该如何让网站刷新或为网页添加书签。有人能帮助我吗?我举了一个例子来帮助澄清。


的index.html

<!DOCTYPE html>

<html>
    <head>
        <meta charset = "utf-8">

        <title>History API</title>

        <script>
            function ajax (url, callback) {
                var conection = new XMLHttpRequest ();

                conection.open ("GET", url, true);

                conection.setRequestHeader ("X-Requested-With", "XMLHttpRequest");

                conection.send (null);

                conection.onreadystatechange = function () {
                    if (conection.readyState === 4) {
                        if (conection.status === 200) {
                            callback (conection.responseText);
                        }
                        else if (conection.status === 404) {
                            alert ("Page not found !");
                        }
                        else {
                            alert ("Error !");
                        }
                    }
                }
            }

            window.addEventListener ("popstate", function (event) {
                var state = event.state;

                if (state) {
                    document.getElementById ("content").innerHTML = state["content"];
                }
            });

            document.addEventListener ("DOMContentLoaded", function () {
                var content = document.getElementById ("content");
                var menu = document.getElementById ("menu");

                menu.addEventListener ("click", function (event) {
                    var target = event.target;

                    if (target.nodeName === "A") {
                        ajax (target.href, function (result) {
                            history.pushState ({"content": result}, target.innerHTML, target.href);

                            content.innerHTML = result;
                        });

                        event.preventDefault ();
                    }
                });
            });
        </script>

        <style>
            body {
                width: 400px;
            }

            div {
                border: 1px solid black;
                padding: 10px;
            }
        </style>
    </head>

    <body>
        <div id = "menu">
            <a href = "page1.html">Page 1</a>
            <a href = "page2.html">Page 2</a>
        </div>

        <div id = "content"></div>
    </body>
</html>

的index.php

<?php
    isset ($_GET["page"]) or exit ("Error !");

    $page = $_GET["page"];

    // Ajax request
    if (isset ($_SERVER["HTTP_X_REQUESTED_WITH"]) && strtolower ($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest") {
        if (file_exists ($page)) {
            require_once ($page);
        }
        else {
            header ("HTTP/1.1 404 Not Found");
        }
    }
    else {
        require_once ("index.html");
    }
?>

page1.html

  

您好,我是第1页。很高兴见到您。

page2.html

  你好兄弟。我是第2页。


点击(确定)

enter image description here

刷新(失败)

enter image description here

1 个答案:

答案 0 :(得分:1)

首先,你真的不应该使用GET参数作为_require_once_的输入。真。不。至少使用一个简单的页面允许名称白名单,只包含和输出映射文件(或带有这些列入白名单的文件)。

现在来看你的历史API问题。推送事物显然似乎对您有用,所以缺少的可能是一个简单的ondomready事件,它读取当前URL并通过AJAX或现有历史记录条目加载内容。应该使用相同的白名单方法。另外,尝试不使用未经验证的输入(URL)作为javascript和DOM操作的输入,从而陷入DOMXSS的陷阱。