API за история, опресняване и отметка

pushState не прави заявка, той просто променя URL адреса и съхранява нов запис в хронологията. Мислейки за тази концепция, невъзможно е да опресните или да маркирате, защото сървърът винаги ще изпълни заявка. Необходимо е решение от страна на сървъра.
След няколко часа търсене намерих решение, всяко отделно обаждане трябва да бъде пренасочено към 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 страница.


Щракване (ОК)

въведете описание на изображението тук

Опресняване (неуспешно)

въведете описание на изображението тук


person Caio    schedule 24.07.2012    source източник


Отговори (1)


Първо, наистина не трябва да използвате GET параметър като вход за _require_once_. Наистина ли. Не. Използвайте поне обикновен бял списък с разрешени имена за страници и включвайте и извеждайте само картографирани файлове (или файлове с тези имена в белия списък).

Сега към вашия проблем с API на историята. Натискането на нещата очевидно изглежда работи за вас, така че всичко, което липсва, вероятно е обикновено ondomready събитие, което чете текущия URL и зарежда съдържанието чрез AJAX или от съществуващи записи в историята. Там трябва да се използва същият подход към белия списък. Също така се опитайте да не попаднете в капана на DOMXSS, като използвате невалидиран вход (URL) като вход за вашите javascript и DOM операции.

person graste    schedule 24.07.2012
comment
Казахте важни неща за сигурността, благодаря. При първа възможност ще се погрижа за тях. - person Caio; 25.07.2012
comment
Ей човек ! Вашият отговор наистина ми помогна, проблемът ми е решен. Благодаря ! - person Caio; 26.07.2012