0

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

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

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


索引.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>

索引.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

你好,我是Page 1。很高兴认识你。

page2.html

嗨,兄弟。我是第2页。


点击(确定)

在此处输入图像描述

刷新(失败)

在此处输入图像描述

4

1 回答 1

1

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

现在到你的历史 API 问题。Pushing things 显然对你有用,所以缺少的可能是一个简单的 ondomready 事件,它读取当前 URL 并通过 AJAX 或从现有历史条目加载内容。应该在那里使用相同的白名单方法。也尽量不要通过使用未经验证的输入(URL)作为您的 javascript 和 DOM 操作的输入而落入 DOMXSS 的陷阱。

于 2012-07-24T19:53:45.260 回答