Правильный способ воссоздать HTML-документ из строки? - PullRequest
0 голосов
/ 20 июня 2011

обо всем по порядку, я дешевый! :) Я не могу позволить себе купить статический IP для своего домена, и я не могу позволить себе эти модные сертификаты ... Так что для меня нет SSL / HTTPS.

Что я пытаюсь сделать здесь, так это развернуть свое собственное «HTTP-шифрование». Вот что я уже сделал:

  1. Изменен существующий прокси-скрипт (Glype / PHProxy) для «шифрования» (пока base64) вывода эха. (Кстати, я оборачиваю весь контент в элемент body)
  2. Написан сценарий GreaseMonkey для «расшифровки» зашифрованного вывода.

Эта штука работает на простых сайтах. Но когда я загружаю сложные веб-сайты (например, браузерную игру), javascript-скрипты не работают (кстати, скрипт может отлично воспроизвести игру, когда я выключил шифрование).

При проверке через FireBug я заметил, что содержимое элемента head помещается в элемент body. Это не всегда происходит, поэтому я подозревал, что PHP генерирует некорректный вывод, но я декодировал base64 с помощью автономного инструмента, и HTML выглядит нормально.

Вот пример вывода из PHP:

<html><body>PGh0bWw+DQo8aGVhZD4NCjx0aXRsZT5IZWxsbzwvdGl0bGU+DQo8L2hlYWQ+DQo8Ym9keT4NCjxoMT5IZWxsbyBXb3JsZDwvaDE+DQo8L2JvZHk+DQo8L2h0bWw+</body></html>

Вот декодированный HTML-код из Firebug (после обработки сценарием GM):

<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>

Вот мой GM-скрипт для декодирования вывода PHP:

function utf8_decode (str_data) {
    var tmp_arr = [],
        i = 0,
        ac = 0,
        c1 = 0,
        c2 = 0,
        c3 = 0;

    str_data += '';

    while (i < str_data.length) {
        c1 = str_data.charCodeAt(i);
        if (c1 < 128) {
            tmp_arr[ac++] = String.fromCharCode(c1);
            i++;
        } else if (c1 > 191 && c1 < 224) {
            c2 = str_data.charCodeAt(i + 1);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = str_data.charCodeAt(i + 1);
            c3 = str_data.charCodeAt(i + 2);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }

    return tmp_arr.join('');
}

function base64_decode (data) {
    var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
        ac = 0,
        dec = "",
        tmp_arr = [];

    if (!data) {
        return data;
    }

    data += '';

    do { // unpack four hexets into three octets using index points in b64
        h1 = b64.indexOf(data.charAt(i++));
        h2 = b64.indexOf(data.charAt(i++));
        h3 = b64.indexOf(data.charAt(i++));
        h4 = b64.indexOf(data.charAt(i++));

        bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;

        o1 = bits >> 16 & 0xff;
        o2 = bits >> 8 & 0xff;
        o3 = bits & 0xff;

        if (h3 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1);
        } else if (h4 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1, o2);
        } else {
            tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
        }
    } while (i < data.length);

    dec = tmp_arr.join('');
    dec = utf8_decode(dec);

    return dec;
}

document.documentElement.innerHTML = base64_decode(document.body.innerHTML);

Мне кажется, проблема в том, что я присваиваю декодированный HTML-код document.documentElement.innerHTML , и таким образом он помещает все это в элемент body ?

Итак, вопрос в том, как правильно воссоздать HTML-документ из строки?

Ответы [ 2 ]

1 голос
/ 20 июня 2011

Поскольку вы просто используете кодировку base 64 и, как сказал @ Battle_707, проблема связана с событиями dom, почему бы вам не отправить страницу с перенаправлением на URL-адрес данных . Таким образом, браузер должен запускать все нужные события.

А если серьезно, просто получите сертификат и зайдите на dyndns.com, Base 64 не требует дополнительной безопасности

Редактировать

Поскольку вы упомянули о переходе на AES, если вы можете найти реализацию JS AES, вы можете использовать мое предложение здесь и создать клиентскую часть URL-адреса данных и перенаправить на нее.

function openPageFromString(html){
    location="data:text/html,"+encodeURIComponent(html);
}
1 голос
/ 20 июня 2011

Проблема с тем, что вы называете «сложными» страницами, состоит в том, что они имеют очень специфические события DOM.Эти события будут инициированы либо когда браузер впервые читает строку, либо по определенным «точкам останова» (например, «onload»).Поскольку вы запутываете код, а затем декодируете его после полной загрузки, ваш браузер не будет перечитывать страницу, чтобы попасть на эти события.Возможно, просто возможно, вы могли бы вызывать каждую функцию из этих событий вручную после загрузки страницы, но я не удивлюсь, если (некоторые) браузеры затруднят вам это, поскольку страница была создана как <html><head></head><body><html>.....your decoded page....</html></body></html>.Это помимо того факта, что движки JS могут вообще не индексировать новый код.

...