Копирование блоков страницы(или целиком)
У меня возникла задача копирования всей страницы, или отдельных блоков ее.
Т.е. мне нужно сохранить(через скрипт страницу) и отправить ее на файл php для обработки ( по идее в переменную ее занести не получится). А скрипт в свою очередь, сохранит ее в файл... Т.е. получится, как бы копирование страницы и сохранение в определенной папке. У меня есть встраиваемый скрипт, который берет со страницы ее юрл и титл. (на JS написаны). А вот как быть со страницей не знаю. Как это можно реализовать? Может, конечно, неправильно выбрал тему. Но я если честно, даже не знаю с чего начать. |
Странно, что это требуется именно на клиенте брать вывод. 0_о
Не очень тривиальная задача. На ум приходит только брать "document.body.innerHTML", а из шапки брать и генерировать на основе свойств document... Потом ajax'ом отправлять это всё через POST на php скрипт... |
Не обязательно на клиенте. Мой php скрипт хранит юрл данной страницы. Если можно подобное реализовать, используя PHP, то так даже лучше. Но, насколько я знаю, то страницы защищены от инклуда(если не с данного сайта он происходит).
|
Нет, с этим нету проблем, если на сервере разрешено сокетное подключение.
На всех платных хостингах оно разрешено. Делается это примерно так: $fp = fsockopen("www.site.ru", 80, $errno, $errstr, 30); if ($fp) { // Генерируем шапку запроса к странице: $out = "GET /path_to_page.php HTTP/1.1\r\n" ."Host: www.site.ru\r\n" ."Connection: Close\r\n" ."\r\n"; // Посылаем запрос на сайт: fwrite($fp, $out); // Получаем ответ: while (!feof($fp)) { $result = fgets($fp, 128); } fclose($fp); // Результатом будет ответ сервера: шапка http + тело ответа, // оно будет разделено двумя переносами "\r\n" так что нужно // будет найти первое вхождение "\r\n\r\n" и отрезать шапку от тела. echo $result; } Подробнее об этом можно почитать тут. Кроме того, тебе понадобятся базовые знания протокола http. |
В принципе можно не заморачиваться с сокетами и просто использовать функцию file_get_contents.
А через JavaScript все равно исходный код страницы не восстановить, т.к. каждый браузер приводит html-код к своему виду. Если у вас установлен плагин к файерфоксу Web Developer Toolbar, то сравните "View source" и "View generated source". В частности, firefox удаляет все xhtml-ные закрытия тегов, а-ля <img />. ИЕ еще больше мудрит: у некоторых значений аттрибутов удаляет кавычки, у некоторых нет. |
Ну да, можно в принципе и через file_get_contents(). Но всё-таки везде есть fsockopen, но кое-где нету fopen wrappers, так что использовать fsockopen тут более рационально. Тем более, для расширения (+cookie, +POST, ...) да и для общего развития полезно использовать fsockopen. Это ИМХО, конечно... :)
|
маленькое замечание: file_get_contents (если параметр - url) внутри себя использует сокетное соединение, так что - без разницы =)
|
Ну да, по сути любое соединение, использующее URL fopen wrappers является сокетным соединением, т.е fopen, file_get_contents, include (раньше) если им передать url в качестве пути, откроют сокетное подключение, т.к это вообще механизм коммуникации между клиентом и сервером.
Всё таки по мне, лучше использовать сделанную именно для таких задач функцию fsockopen, чем функции работы с локальными файлами с параметром url. Да и если приложение нужно будет расширить, например получить страницу, сгенерированную POST запросом, или с определёнными куками, или получить через https, то тут уже легче самому запрос генерировать, чем писать неудобный (имхо) контекст для file_get_contents. В любом случае, решать автору :) |
Цитата:
Вот, подправил немного код. Исправил ошибку, и сделал более универсальным: function par_str($str,$start,$end){ $res = substr($str,strpos($str,$start)+strlen($start),strlen($str)); if ($end!=null) $res = substr($res,0,strpos($res,$end)); echo($res); return $res; } function get_contents($url){ $url_host = par_str($url,"http://","/"); $url_get = par_str($url,$url_host,null); $fp = fsockopen($url_host, 80, $errno, $errstr, 30); if ($fp) { $out = "GET ".$url_get." HTTP/1.1\r\n" ."Host: ".$url_host."\r\n" ."Connection: Close\r\n" ."\r\n"; fwrite($fp, $out); $result=""; while (!feof($fp)) { $result .= fgets($fp, 128); } $result=substr($result,strpos($result,"\r\n\r\n")+4,strlen($result)); $result=substr($result,strpos($result,"\r\n")+2,strlen($result)); fclose($fp); return $result; } } а ошибка была у тебя, точку надо поставить, что бы объединить все: while (!feof($fp)) { $result .= fgets($fp, 128); } |
Возникла проблема с кодировкой... При отображении в браузере, все нормально. если я пытаюсь отправить эту страницу на мыло. То некоторые приходят нормально, а некоторые в непонятной кодировке...
Пример: "µРїРѕСЃС‚СЊ - Главная страница". Как этого можно избежать? и перекодировать(или другие способы) что бы на мыло приходил нормальный текст. |
Phoenix, а на мыле у каждого своя кодировка (к тому же почти все сервисы и почтовые клиенты имеют возможность перекодировки). Если интересует текст в конкретной кодировке, можно преобразовать ее (например, функцией iconv(...) (или даже свою написать)) + в дополнении указать кодировку в header'e письма.
|
Цитата:
|
про "iconv(...)" я знаю... но вот задача.. определить в какой кодировке страница(строка). Нашел функции. но многие некорректно работают. ищу дальше...
|
Phoenix, да, поищи, у меня только на памяти mb_detect_encoding(...), да и то для ее работы должен быть модуль php_mbstring включен.
|
Цитата:
На сколько я понял, обмен данными возможен только между родительским и дочерними окнами :( Следовательно, все же придется использовать AJAX. Или есть способы взаимодействия двух(не связаных окон между собой)? |
Phoenix,
Цитата:
Цитата:
Цитата:
|
Цитата:
|
В общем, чтоб не парится, попробуй поработать с классом Snoopy, там очень просто сделать и поддержание сессии, и установку cookies. JavaScriptом тут делать не рационально.
Стоит ли в твоей задаче получить содержание страницы, которую открыл авторизированный пользователь (логин и пароль которого ты не знаешь), и которая не видна без авторизации? Тут такой парсинг (через сокеты) будет невозможен. Да и кстати, через ajax разве можно сделать кроссайтовую передачу данных? Вообще, опиши полностью задачу, тебе надо проверять есть ли в странице определённый элемент, или нужно сохранить документ в его определённом состоянии? Если расскажешь суть задачи, может тогда сможем помочь тебе определиться с выбором алгоритма "забирания" страницы. |
Цитата:
|
Kolyaj,
Хм, а тут написано что через традиционный ajax - нет :) Цитата:
|
Андрей Параничев, через "традиционный" нет конечно - это противоречит политике безопасности. Но я говорил о том, что аякс вызовет свой скрипт (в пределах своего домена), который в свою очередь уже отправит сокет-запрос на другой домен.
|
Андрей Параничев,
я кстати вообще не использую аббревиатуру ajax, т.к. она только путает. В частности я не говорил, что нужно использовать XMLHttpRequest. Допустим, нам нужно передать данные на другой домен и получить ответ. Мы создаем элемент script, в get-параметрах передаем данные, а нам возвращается ответ в виде js-кода, который, допустим, вызывает callback-функцию. |
Цитата:
Сейчас склоняюсь к идее отправлять GET параметром document.body.innerHTML(уже работает, но криво). Но столкнулся с новой проблемой. Как быть с символами #,?,&... Ведь мой скрипт, когда парсит GET параметры неправильно будет определять тогда document.body.innerHTML. П.С. у меня есть полный доступ к странице со стороны JS, данные совему скрипту я отправляю через GET параметры... |
Если я правильно понимаю.. то через rawurlencode() надо пройти весь document.body.innerHTML. для замены символов их кодами.... и отправлять втаком виде в GET параметре...
Надюесь поможет. |
маленькое замечание: Phoenix, GET имеет ограниченную длину, так что большой документ не передашь.
|
Phoenix,
создай динамически форму с методом post, и в ней содержимое отправляй в скрытый iframe (если ответ конечно не нужен). |
Хм... так получается отправлять надо со скрытово iframe( что бы не обновлять страницу и к AJAX не прибегать)...
Вот, сделал функцию.. которая отсылает данные о странице на мыло... Но одна две проблемы: 1. Т.к. форма встраивается в страицу, то при субмите, страница обновляется. Как это можно избежать? если добавить фрейм? и только его обновлять(отправлять). 2. Не так значательно... Возможно ли с письмом отправить css файл? п.с. у меня страница идет как тело документа, но хеадер Content-Type: text/html. Возможно ли, через mail() отправлять письма с прикрепленными файлами? Вот сама функция: <a href='javascript:(function(){ var s=document.createElement("script"); s.charset="windows-1251"; s.language="javascript"; s.type="text/javascript"; var form=document.createElement("form"); form.id=form.name="page"; form.method="post"; form.action="test.php"; var tit=document.createElement("input"); tit.type="text"; tit.id=tit.name="stitle"; form.appendChild(tit); var area=document.createElement("textarea"); area.id=area.name="sbody"; form.appendChild(area); var inf=prompt("Введите описание ссылки", ""); if (inf!=null) { tit.value=inf+"-"+document.title; alert("test"); document.body.appendChild(form); alert("test2"); area.value=document.body.innerHTML; document.body.appendChild(s); form.submit(); }else{alert("Не определен");} alert("test3");})();' return false>[Добавить URL в базу]</a> |
Цитата:
Код-то в соответствующие теги запихните, как это читать-то? |
Я чуть чуть изменил, открываю в отдельном окне. форму и отправляю. получилось даже лучше. Вот одна проблема....
document.body.innerHTML - полностью игнорирует CSS файл... и заголовок. Как это можно обойти? и добавить к document.body.innerHTML И еще одна проблема... Когда отправляется форма, то все символы " и ' переделываются в \" и \' как это можно убрать? парсить весь текст не хочется... думаю эт можно проще сделать. Но не знаю как |
с обратными слешами разобрался... Осталось только получения мета данных и линки на сss. На JS это можно сдлеать?
|
alert(document.getElementsByTagName('HTML')[0].innerHTML); В FF работает. |
Часовой пояс GMT +3, время: 12:18. |