|
|
|
| не понимаю, можно ли вообще так делать и как правильно.
на страничке есть кнопка, по нажатию аякс-запрос посылает на сервер изображение
xhr.open("post", "doImg.php", true);
xhr.send(form);
|
файл doImg.php обрабатывает это изображение и возвращает обратно
header('Content-Type: image/jpeg');
imagejpeg($dest);
|
и вот что теперь делать в функции обрабатывающей ответ сервера ???
xhr.onload = function(data) {
// ???
};
|
ответ приходит типа
����JFIF��>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality
��C....
я хочу, чтобы генерировалось сохранение в файл на пк пользователя (т.е. появляется стандартное предложение браузера: сохранить файл или открыть...)
Не понимаю как это сделать и возможно ли.
Помогите, пожалуйста, разобраться.
Спасибо! | |
|
|
|
|
|
|
|
для: poli
(23.05.2013 в 09:38)
| | А разве Ajax может отправлять бинарные данные? | |
|
|
|
|
|
|
|
для: confirm
(23.05.2013 в 10:07)
| | извините, пожалуйста, я не большой дока, не совсем понимаю ваш вопрос.
но момент с отправкой данных у меня работает, вопрос относится к ответу сервера
поменяла код в doImg.php, теперь сервер возвращает картинку в base64
header('Content-Type: image/jpg');
imagejpeg($dest, '1.jpg', 75);
if($fp = fopen('1.jpg',"rb", 0))
{
$gambar = fread($fp,filesize('oli.jpg'));
fclose($fp);
}
echo "data:image/jpg;base64,".chunk_split(base64_encode($gambar));
|
функция onload, которая его принимает выводит данные в картинку
xhr.onload = function(data) {
console.log("Upload complete.");
var new_img = new Image();
new_img.src = data.target.responseText;
window.document.body.appendChild(new_img);
};
|
Но я хочу, чтобы браузер предлагал сразу сохранить картинку в файл,
а так придется еще кнопочку ставить "сохранить результат" | |
|
|
|
|
|
|
|
для: poli
(23.05.2013 в 10:28)
| | Значит вы не верно ставите вопрос - у вас сервер отдает клиенту изображение как кодированную в base64 строку, в ответ на асинхронный запрос, а не наоборот как вы пишите - Ajax посылает на сервер изображение...
Не может он такого сделать просто напросто. Объект используемый в Ajax (текущая версия) отправляет на сервер только текстовые поля, radio/cechbox и кнопки, поля типа file игнорируются, даже если вы передадите соответствующие заголовки. Из современных браузеров передать на сервер изображение в нынешней версии Ajax можно только в Firefox, с помощью нового функционала форм в HTML5. И это можно сделать как раз опять с помощью base64.
Загрузка изображений на сервер посредством Ajax будет поддерживаться в следующей версии (по крайней мере ожидается такое).
Это то, о чем вы не поняли. Что касается сохранить переданное сервером изображение, да еще как строку, сразу на клиенте - этого сделать нельзя без согласия пользователя, вообще ничего нельзя сохранить без его ведома. Так что только если он захочет. Но в вашем случае кнопочка "сохранить результат" не поможет, так как не обладает браузер возможностью сохранять строку некую, которую вы как либо передали. Можно ее только скопировать и сохранить. Можно отдавать пользователю файл, а он будет выбирать "Сохранить как...".
Тоже самое и с вашим изображением - чтобы у пользователя была возможность сохранить это изображение, он должен видеть не кнопочку "сохранить что-то...", ибо для браузера это будет NULL, а видеть изображение. И даже была бы такая возможность, то сохранялось бы не изображение, а строка - не ожидайте, что браузер при этом автоматом бы преобразовал ее в бинарный вид. Если строка base64 описывающая это изображение не превышает определенного размера для конкретного браузера (у каждого свои ограничения), то это изображение можно отобразить на странице, а уже щелкнув по нему, пользователь может выбрать "Сохранить...". По другому никак.
PS. Это
var new_img = new Image();
new_img.src = data.target.responseText;
window.document.body.appendChild(new_img);
заменяется одной строкой
<img src="data:image/ТИП;base64, СТРОКА BASE64.... | |
|
|
|
|
|
|
|
для: confirm
(23.05.2013 в 10:48)
| | confirm спасибо за ответ!
но все еще я не понимаю, что же мне нужно прописать в функции-обработчике ответа с сервера.
по поводу передачи файлов ajax - как вы пишете про html5 "ожидается" - будущее уже наступило http://caniuse.com/#search=FormData
по кр. мере я юзаю хром, и кроссплат. меня в данном сл. не интересует.
по поводу "сохранить переданное сервером изображение", мне и не нужно без ведома пользователя, мне нужно чтобы инициировалась обычная загрузка файла, как это происходило бы, не используй я аякс-запроса,
заголовки
header('Content-Type: image/jpeg');
header("Content-Disposition: attachment; filename= img.jpg");
|
предложили бы пользователю загрузить файл (захочет пользователь или нет - его дело, но сейчас это предложение подавляется аяксом - вот в чем проблема)
но у меня аякс, и я не знаю, что мне нужно написать в функции, которая ждет ответ от сервера, потому, что данные-то приходят ( я вижу их в панели разработчика), но естественно никуда не выводятся (так как у меня нет соответ. обработки получаемых результатов). | |
|
|
|
|
|
|
|
для: poli
(24.05.2013 в 10:52)
| | Вот я и прошляпил расширения XMLHttpRequest 2 в HTML5.
Ну значит вы не так поступаете - плохо, что сервер возвращает строку base64, это и длиннее оригинала в три раза, и если превысит размер допустимый, значит не увидит картинку пользователь. А ведь, если вы читали о новых возможностях, то должны знать, что можно и принимать бинарные данные.
Есть в HTML5 и возможность сохранения принятых данных, но не на диск, как это бы происходило при скачивании, а в локальное хранилище, короче в "песочницу". Все это политика безопасности. Поэтому если сохранить на диск, то можно сохранить файл в сессии, а кнопка это запрос на скачивание файла по параметру (отдача скриптом). Иначе никак.
Если работать не в рамках html-страницы, а в рамках системы (например, речь идет об административном управлении), то можно сохранить и на диск, и все что угодно сделать (у JS не будет ограничений) и без танцев. | |
|
|
|
|
|
|
|
для: poli
(24.05.2013 в 10:52)
| | Если я правильно понял задачу (т.е. по запросу нужно чтоб сервер выдал предложение сохранить картинку), то вам ajax не нужен. Вам нужно:
document.location = 'doImg.php';
|
А doImg должен работать так, как у вас было в самом начале
<?php
header('Content-Type: image/jpeg');
imagejpeg($dest);
|
Если у вас ajax'oм отправляется и обрабатывается картинка, то вам нужно не возвращать саму картинку клиенту, а сохранить ее на сервере в какой-нить временной папке и передать клиенту только адрес этого файла. А клиент, получив адрес нового изображения, опять же должен выполнить
document.location = 'temp_img_file.jpg';
| при этом никакого перехода не будет, а выскочит именно окно с предложением сохранить картинку.
_______
P.S.
"при этом никакого перехода не будет, а выскочит именно окно с предложением сохранить картинку."
Вообще в этом не уверен.... Если браузер вместо предложения сохранить, перейдет и отобразит картинку, то замените
header('Content-Type: image/jpeg');
| на
header('Content-Type: application/octet-stream');
|
| |
|
|
|
|
|
|
|
для: Sfinks
(24.05.2013 в 12:33)
| | Не так всё просто. Там же postом отправляется сначала на обработку файл, а потом нужно получить результат. Сами же написали, что на диск надо сохранять сначала. Средства XMLHttpRequest не позволяют получить ответ с бинарными данными в onload и сразу выдать данные пользователю с нужными заголовками. Хотя решение есть наверно, но не искал.
Можно сделать так (не тестировал)
Заменить
header('Content-Type: image/jpeg');
imagejpeg($dest);
|
на
if($_GET['img']){
$imgname = (int)$_GET['img'];
$filepath = "folder/". $imgname .".jpg";
if(file_exists($filepath)) {
header("Content-Type: image/jpeg");
header("Content-Disposition: attachment; filename=". $imgname .".jpg");
readfile($filepath);
}
exit();
}
$t = time();
imagejpeg($dest, "folder/". $t .".jpg");
echo $t;
|
folder - папка сохранения картинок (с правами на запись)
в js:
xhr.onload = function(e) {
document.location = 'doImg.php?img=' + xhr.responseText;
};
|
И всё по идее.
Второй вариант проще - делать прямое обращение к картинке
document.location = 'temp_img_file.jpg';
|
но в папке с картинками тогда придется создать .htaccess c содержимым
ForceType application/octet-stream
Header add Content-Disposition "attachment"
|
но это не на любом сервере будет работать ещё. | |
|
|
|
|
|
|
|
для: DangerBay
(24.05.2013 в 13:52)
| | ребята, спасибо за помощь!
все "срослось" :)
confirm, спасибо за учасите.
Sfinks, спасибо, вы совершенно правильно поняли задачу, дали верное направление решения. сомнения были оправданы:
прямое обращение к картинке
document.location = 'temp_img_file.jpg';
|
отображает картинку.
И вы еще раз правы, можно было обойтись без аякса (я теперь тоже это понимаю, но я делала аякс-загрузку, поскольку изображения получала с помощью drag-and-drop, а не стандартного input type="file", теперь, чтобы сделать тоже самое без аякса, нужно доработать js-часть по загрузке изображения на сервер)
DangerBay, спасибо, ваш комментарий помог получить ожидаемый результат. Обращение в document.location к php-файлу - именно то, чего не доставало.
через аякс получилось так
1) js:
оформляю нужные данные и передаю на сервер
xhr.open("post", "doImg.php", true);
xhr.send(form);
|
2) doImg.php:
обрабатывает полученный файл и сохраняет его во врем. файл,
возвращает код файла
код DangerBay (24.05.2013 в 13:52)
3) js:
принимает ответ сервера и просит вернуть обработанное изображение
xhr.onload = function(data) {
document.location = 'doImg.php?img=' + xhr.responseText;
};
|
4) doImg.php?img=:
возвращает обработанный файл
код DangerBay (24.05.2013 в 13:52)
а заголовки "говорят" браузеру вывести окно "Сохранить как..."
что и требовалось...
Без аякса в данном случае, наверное, будет правильнее хотя бы с той т. зрения, что уменьшается колич-во обращений клиента к серверу...
еще раз спасибо, что помогли разобраться. | |
|
|
|
|
|
|
|
для: poli
(23.05.2013 в 09:38)
| | Чтобы браузер предложил сохранить файл:
header('Content-Type: image/jpeg');
header("Content-Disposition: attachment; filename=" . $my_filename );
imagejpeg($dest);
|
в $my_filename имя картинки, например, pic123.jpg
В $dest получение из $_FILES и дальнейшая обработка картинки, но это уже и так есть, как я понимаю. | |
|
|
|
|
|
|
|
для: DangerBay
(23.05.2013 в 15:15)
| | DangerBay, спасибо за заголовки,
но у меня проблема их принять, как уже и написала выше.
т.е. проблема в js-скрипте обработать,
наверное, мне нужно с этим вопросом на форум javaScript? | |
|
|
|
|