можно ли просмотреть локальные изображения перед их загрузкой через форму?

Чтобы быть более конкретным, я хочу использовать форму с одним или несколькими полями ввода файлов, используемыми для изображений. Когда эти поля изменены, я хотел бы показать предварительный просмотр связанного изображения перед отправкой данных на сервер.

Я пробовал несколько подходов к javascript, но всегда сталкивался с ошибками безопасности. Я бы не возражал против использования java или flash, пока решение изящно деградировало для тех пользователей, у которых их не было. (Они не получат предварительный просмотр и не получат раздражающего «установите эту штуку».)

Кто-нибудь сделал это простым, многоразовым способом?

P.S. Я знаю, что есть песочница, но должна ли песочница находиться в темной, запертой комнате с затемненными окнами?


person Matt Van Horn    schedule 28.05.2009    source источник
comment
Вы не можете просмотреть свое изображение, не загрузив его перед этим. Я не знаю, можно ли это сделать с помощью Flash, возможно, с помощью Java, но я думаю, что это было бы похоже на попытку убить муху молотком. Вы можете выполнить симулированную загрузку Ajax с помощью iframe, в сети есть несколько примеров, и они работают довольно хорошо.   -  person Fabien Ménager    schedule 28.05.2009
comment
Ознакомьтесь с этим чистым подходом JavaScript, включая его ответ и комментарий Рэя Николуса для окончательного решения: stackoverflow.com/questions/16430016/   -  person Jonathan Root    schedule 17.10.2013


Ответы (6)


Не нужно вычурных вещей. Все, что вам нужно, это функция createObjectURL, которая создает URL-адрес, который можно использовать в качестве изображения src и который можно получить прямо из локального файла.

Допустим, вы выбрали пару изображений с компьютера пользователя с помощью элемента ввода файла (<input type="file" />). Вот как вы могли бы создать превью файлов изображений для него:

function createObjectURL(object) {
    return (window.URL) ? window.URL.createObjectURL(object) : window.webkitURL.createObjectURL(object);
}

function revokeObjectURL(url) {
    return (window.URL) ? window.URL.revokeObjectURL(url) : window.webkitURL.revokeObjectURL(url);
}

function myUploadOnChangeFunction() {
    if(this.files.length) {
        for(var i in this.files) {
            var src = createObjectURL(this.files[i]);
            var image = new Image();
            image.src = src;
            // Do whatever you want with your image, it's just like any other image
            // but it displays directly from the user machine, not the server!
        }
    }
}
person dev    schedule 03.10.2011
comment
Работает, но только в Chrome 18, Chromium 18, Firefox 11. Не работает в Safari, IE 9 и в опере не проверял. jsfiddle.net/M3kj6/1 Я поработаю над этим позже, чтобы посмотреть, смогу ли я заставить его работать в саф & т.е. В любом случае интересно... :) - person ; 17.04.2012
comment
Это наиболее подходящий способ для этой задачи. В соответствии с этим: developer.mozilla.org/en-US/ docs/DOM/window.URL.createObjectURL уже работает в IE 10 и Opera. - person Konstantin Smolyanin; 24.02.2013
comment
единственное, не используйте for(var i in something) для массивов stackoverflow.com/questions/500504/ - person Alex K; 25.03.2015

Первый шаг — узнать путь к изображению. JavaScript разрешено опрашивать элемент управления загрузкой для имени файла/пути, но (из соображений безопасности) различные браузеры показывают разные вещи для механизма JS, чем они отображают для пользователя - они, как правило, сохраняют имя файла нетронутым, поэтому вы можете, по крайней мере, проверить его расширение, но вы можете получить c:\fake_path\ или другую подобную запутанную вещь, добавленную к имени файла. Попробовав это в различных браузерах, вы получите представление о том, что возвращается как реальный путь, а что подделывается и где.

Второй шаг — отображение изображения. Можно отображать локальные изображения, если вы знаете их пути, через img теги с file:// исходными URL-адресами, если браузер пользователя поддерживает схему file://. (По умолчанию Firefox этого не делает.) Поэтому, если вы можете заставить пользователя сообщить вам полный путь к изображению, вы можете, по крайней мере, попытаться загрузить его.

person Dan Davies Brackett    schedule 28.05.2009

JavaScript не имеет доступа к локальной файловой системе в целях безопасности, и точка.

person Diodeus - James MacFarlane    schedule 28.05.2009
comment
Это идиотизм с точки зрения безопасности. Такой файл нельзя отправить на сервер, так для чего это? Я видел много веб-игр, в которых есть возможность загрузки графики на жесткий диск, поэтому игра работает быстрее. - person Thinker; 28.05.2009
comment
Мыслитель, это обычно достигается с помощью кэширования HTTP - это совершенно другое. JS по-прежнему не имеет доступа к путям в файловой системе клиента. - person Dan Davies Brackett; 28.05.2009
comment
За исключением того, что теперь есть файловый API HTML5, который ДЕЙСТВИТЕЛЬНО дает вам доступ для чтения к загружаемым файлам. И это безопасно - person Idris Mokhtarzada; 12.04.2011

Вот скрипт jQuery + PHP для загрузки изображение предварительного просмотра.

person Jamis Charles    schedule 28.05.2009
comment
этот загружает изображение перед его показом. четкий код, однако - person Javier; 28.05.2009

Я только когда-либо видел апплеты Java, которые делают это, например, апплет загрузки изображений на Facebook. Недостатком подхода Java является то, что пользователю будет предложено доверять аплету перед его запуском, что является своего рода раздражением, но это позволяет аплету представить файловый браузер с предварительным просмотром изображений или делать более интересные вещи, такие как позволяет пользователю загрузить весь каталог.

person Dietrich Epp    schedule 28.05.2009

Вы можете попробовать этот подход, хотя кажется, что он не работает в IE.

http://saravani.wordpress.com/2012/03/14/preview-of-an-image-before-it-is-uploaded/

Это просто и быстро кодировать.

Я помещаю код здесь на случай, если исходник умрет:

Скрипт:

    <!-- Assume jQuery is loaded -->
    <script>
      function readURL(input) {
        if (input.files && input.files[0]) {
          var reader = new FileReader();

          reader.onload = function (e) {
            $('#img_prev')
              .attr('src', e.target.result)
              .width(150)
              .height(200);
          };

          reader.readAsDataURL(input.files[0]);
        }
      }
    </script>

В HTML:

    <!--[if IE]>
      <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    </head>
    <body>
      <input type='file' onchange="readURL(this);" />
      <img id="img_prev" src="#" alt="your image" />
    </body>
person Puce    schedule 16.02.2015