Файл не выбран загрузить файл
Время неумолимо идёт вперёд, а платформа 1С 8 бежит ещё быстрей этого времени.
Управляемые формы теперь называются "интерфейс ТАКСИ", модальные окна запрещены, а режим использования синхронных вызовов расширений и внешних компонент наглухо положил работоспособность большинства этих расширений и внешних компонент, и половину старых методов в добавок.
В общем, пацаны, дела такие - многие из вас читали статью великолепного Чистова П. о работе с файлами в 8.3
Если Вы ещё этого не сделали - бегом марш! (ссылка)
Суть механизма работы с файлами в кратце:
1) На клиенте выбираем файл
2) Пихаем его в чёрный ящик
3) Сохраняем содержимое чёрного ящика на сервере
Загвоздка состоит в том, что делать это надо особенно, по-новому и с душой.
и прочие языческие штучки здесь не прокатят.
Вот листинг кода, который позволяет загрузить файл с клиента
Нас интересует метод "НачатьПомещениеФайлов", который, собственно, вызывает диалог выбора файла и помещает этот файл во временное хранилище. Заморачиваться с описанием временного хранилища нет смысла, просто запомните - это то место, куда помещаются все выбранные нами файлы в виде двоичных данных (черный ящик).
Понять, что там и как храниться в этом временном хранилище практически невозможно. Можно только обратиться к нашему файлу по навигационной ссылке, которая присваивается автоматически (см. переменную "Адрес").
С тем, что файлы нужно хранить в реквизите или ресурсе с типом "Хранилище значения", спорить, думаю, никто не будет. Достать файл из временного хранилища и поместить его в реквизит с типом "Хранилище значения" можно след.образом:
С одним разобрались, теперь второе - как достать файл из этого хранилища значений (которое, напомню, находится на сервере) и сохранить на диск клиента?
Прежде всего, нам надо получить навигационную ссылку на реквизит с типом "Хранилище значения", куда у нас помещается файл в виде бинарных данных.
Будьте, внимательны! Эта навигационная ссылка уже не имеет с временным хранилищем ничего общего! Проверить тип навигационной ссылки можно методом
По традиции, листинг кода, который вызывает диалог сохранения файла
Значение переменной "Файл" это ещё одна особенность данного способа. Здесь стоит обратить внимание на "ИмяФайла". Дело в том, что помещая файл во временное хранилище, информация о его имени и расширении теряется. Поэтому не забудьте где-нибудь сохранять корректное имя файла, или хотя бы его расширение, чтобы потом не мучаться с вопросом "А это вордовский документ или мп3?"
Метод "НачатьПолучениеФайлов" аналогичен методу "НачатьПомещениеФайлов". Просто один открывает диалог для выбора файла, другой же, наоборот, открывает диалог для сохранения файла.
При использовании данного способа, никакие совместимости модальности и синхронных вызовов в свойствах конфигурации устанавливать не нужно.
у меня есть кнопка "Выбрать файл" следующим образом (я использую Jade, но он должен быть таким же, как Html5):
в браузере это показывает кнопку с текстом рядом с ним "нет выбранного файла". Я хотел бы изменить текст "Нет выбранного файла" на что-то другое, например "нет выбранного видео" или "выберите видео, пожалуйста". Я следовал первым предложениям здесь:
Я не хочу видеть "нет выбранного файла" для поля ввода файла
но это не изменило текст:
может кто-нибудь помочь мне выяснить, где проблема?
Я уверен, что вы не можете изменить метки по умолчанию на кнопках, они жестко закодированы в браузерах (каждый браузер отображает заголовки кнопок по-своему). Проверьте это кнопка стиль статьи
скрыть ввод с помощью css, добавить метку и назначить ее кнопке ввода. метка будет кликабельной, и при нажатии на нее запустится диалоговое окно файла.
затем стиль метки в виде кнопки, если вы хотите.
- скрыть ввод и добавить кнопку "файлы"
- затем вызовите кнопку "файлы" и попросите его связать fileupload (я использую JQuery в этом примере)
но если вы попытаетесь удалить эту подсказку
это не будет работать. Вот мой маленький трюк, чтобы работать с этим, попробуйте название с пробелом. Это сработает.:)
попробуйте это просто трюк
как это работает
Это очень просто. элемент Label использует тег " for " для ссылки на элемент формы по идентификатору. В этом случае мы использовали "img" В качестве опорного ключа между ними. Как только это будет сделано, всякий раз, когда вы нажимаете на метку, он автоматически запускает событие щелчка элемента формы, которое является событием щелчка элемента файла в нашем случае. Затем мы делаем элемент файла невидимым с помощью display:none и not видимость: скрытый, чтобы он не создавал пустое пространство.
наслаждайтесь кодирования
Я хотел бы удалить всплывающую подсказку «Файл не выбран» из файла, введенного в Google Chrome (я вижу, что подсказка не отображается в Firefox).
Обратите внимание, что я говорю не о тексте внутри поля ввода, а о всплывающей подсказке, которая появляется, когда вы наводите курсор мыши на ввод.
Я пробовал это без везения:
применение / х-WWW-форм-urlencoded
Теперь измените enctype к application/x-www-form-urlencoded , перезагрузите браузер и повторите.
Ясно, что данные файла не были отправлены, только базовые имена. Так что это не может быть использовано для файлов.
Что касается текстового поля, мы видим, что обычные печатаемые символы, такие как a и b были отправлены в один байт, а непечатные символы, такие как 0xCF и 0x89 занимают 3 байта каждый %CF%89 :!
Файл для скачивания
К публикации прилагается пример, который можно использовать как шаблон для описанных операций. В нем реализованы несколько наиболее востребованных случаев: выбор существующего файла, выбор имени файла для сохранения, выбор каталога и множественный выбор. Для полноты картины приведены аналогичные операции для обычных форм. Тестировались процедуры на платфроме 8.3, на конфигурацях начиная с режима совместимости 8.2.13
23 ответа
Это встроенная часть браузеров webkit , и вы не можете удалить ее. Вам следует подумать о хакерском решении, таком как покрытие или скрытие входных файлов.
Лучшее решение для меня - это обернуть input [type = "file"] в оболочку и добавить код jquery:
Я придумал хакерское решение, которое полностью удаляет «Файл не выбран» плюс дополнительное пространство, добавляемое после этого текста (в Chrome я получаю что-то вроде: «Файл не выбран»).
Это полностью испортило мое выравнивание страниц, поэтому я действительно боролся с этим, чтобы найти решение. Внутри атрибута стиля входного тега установка «ширины» в ширину кнопки устранит конечный текст и пробелы. Так как ширина кнопки не одинакова во всех браузерах (например, она немного меньше в Firefox), вы также захотите установить цвет стиля на тот же цвет, что и на фоне страницы (в противном случае - «блуждающий» Нет "может просвечивать). Мой тег входного файла выглядит так:
Подсказка по умолчанию может быть отредактирована с помощью атрибута title
Но если вы попытаетесь удалить эту подсказку
Это не сработает. Вот мой маленький трюк, чтобы попробовать это, попробуйте название с пробелом. Это сработает.:)
Вы можете отключить всплывающую подсказку, задав заголовок с пробелом в веб-браузерах, таких как Chrome, и пустую строку в Firefox или IE (протестировано в Chrome 35, FF 29, IE 11, Safari Mobile).
Очень просто, забудьте про CSS, предназначенный для ввода ["type"), это не работает для меня. Я не знаю почему. Я получил свое решение в своем теге HTML
Это хитрый. Я не смог найти способ выбрать элемент «no file selected», поэтому создал маску с помощью псевдо-селектора: after.
Мое решение также требует использования следующего псевдо-селектора для стиля кнопки:
К вашему сведению: это будет работать только в браузерах webkit.
P.S., если кто-нибудь знает, как просматривать псевдо-селекторы webkit, такие как приведенный выше в инспекторе webkit, пожалуйста, дайте мне знать
Объединяя некоторые из предложений выше, используя jQuery, вот что я сделал:
И поместите класс "неиспользуемый" в ваши входные данные файла. Это просто и работает довольно хорошо.
Для меня, я просто хотел, чтобы текст был невидимым и все еще использовал кнопку браузера.
Мне нравятся все предложения от undefined, но у меня был другой вариант использования, надеюсь, это поможет кому-то в той же ситуации.
Вам нужно будет настроить контроль довольно много, чтобы достичь этого.
Во всех браузерах и просто. это сделало это для меня
Напрямую вы не можете многое изменить в input [type = file].
Установите непрозрачность файла типа ввода: 0 и попробуйте поместить относительный элемент [div / span / button] поверх него с помощью пользовательского CSS
Все ответы здесь сильно усложнены или, в противном случае, совершенно неверны.
Я создал эту скрипку самым простым способом. При нажатии кнопки «Выбрать файл» откроется меню выбора файла. Затем вы можете стилизовать кнопку так, как вам хочется. По сути, все, что вам нужно сделать, это скрыть введенный файл и вызвать искусственный щелчок по нему при нажатии другой кнопки. Я протестировал это на IE 9, FF и Chrome, и все они работают нормально.
Сюрприз, чтобы никто не упомянул о event.preventDefault()
Затем вы можете использовать различные стили, такие как width , height или другие свойства, чтобы создать свой собственный входной файл.
Оберните и сделайте невидимым. Работа в Chrome, Safari && FF.
Даже если вы установите прозрачность на ноль, появится всплывающая подсказка. Попробуйте visibility:hidden на элементе. Это работает для меня.
Этот работает для меня (по крайней мере, в Chrome и Firefox):
Я нашел очень простое решение, просто установил пустую строку в атрибуте title.
Пройдите -webkit-appearance: . В любом случае стоит попробовать.
Надеюсь, это поможет :)
Лучше избегать использования ненужного JavaScript. Вы можете воспользоваться тегом label, чтобы расширить цель щелчка ввода, например:
Несмотря на то, что ввод скрыт, ссылка по-прежнему работает для него как цель щелчка, и вы можете стилизовать ее так, как хотите.
Вы можете установить ширину для вашего элемента, который будет показывать только кнопку и скрывать «файл не выбран».
Когда я отправляю простую форму вроде этого с прикрепленным файлом:
Некоторое время я не использовал анализатор, но если вы хотите увидеть, что отправляется в вашем запросе (поскольку он направлен на сервер, это запрос), прослушайте его. Этот вопрос слишком широк. ТАК больше для конкретных вопросов программирования.
. как снифферы, мой выбор - скрипач . Вы даже можете создавать свои собственные тестовые запросы, чтобы увидеть, как они публикуются.
Я нахожу MAX_FILE_SIZE странным. как я могу изменить свой HTML-код в Chrome до 100000000, прежде чем публиковать его, так что он публикует лучшее значение. Либо 1. поместите его в файл cookie с безопасным хешем через соль, чтобы при изменении файла cookie сервер мог проверять и выдавать исключения (как это делают веб-части или игровые рамки), либо проверять какую-либо форму, чтобы ничего не изменилось. @ 0xSina
Давайте посмотрим, что происходит, когда вы выбираете файл и отправляете форму (для краткости я обрезал заголовки):
ПРИМЕЧАНИЕ. Каждой граничной строке должен предшествовать дополнительный символ -- , как в конце последней граничной строки. Пример выше уже включает это, но это может быть легко пропустить. Смотрите комментарий @Andreas ниже.
Вместо URL, кодирующего параметры формы, параметры формы (включая данные файла) отправляются в виде разделов в многочастном документе в теле запроса.
В приведенном выше примере вы можете увидеть входные данные MAX_FILE_SIZE со значением, заданным в форме, а также раздел, содержащий данные файла. Имя файла является частью Content-Disposition заголовка.
@ source.rar: Нет. Веб-серверы (почти?) всегда имеют многопоточность, чтобы они могли обрабатывать параллельные соединения. По сути, процесс-демон, который прослушивает порт 80, немедленно выполняет задачу обслуживания другому потоку / процессу, чтобы он мог вернуться к прослушиванию другого соединения; даже если два входящих соединения приходят в один и тот же момент, они просто будут находиться в сетевом буфере, пока демон не будет готов их прочитать.
Объяснение многопоточности немного неверно, поскольку существуют высокопроизводительные серверы, которые спроектированы как однопоточные и используют конечный автомат для быстрой загрузки пакетов данных из соединений по очереди. Скорее, в TCP / IP порт 80 является портом прослушивания, а не портом, на который передаются данные.
Когда прослушивающий сокет IP (порт 80) получает соединение, на другом порту создается другой сокет, обычно со случайным числом выше 1000. Затем этот сокет подключается к удаленному сокету, оставляя порт 80 свободным для прослушивания новых соединений.
Обратите внимание, что строка границы, которая передается как часть поля заголовка Content-Type, на 2 символа короче, чем строка границы для отдельных частей ниже. Я только что потратил час, пытаясь выяснить, почему мой загрузчик не работает, потому что довольно трудно заметить, что на самом деле в первой граничной строке есть только 4 черты, а в других граничных строках - 6. Другими словами: при использовании граничной строки для разделения отдельных данных формы перед ней должны стоять две черточки: - Конечно, это описано в RFC1867, но я думаю, что и здесь следует указать
- добавить еще несколько ссылок HTML5
- объясните, почему он прав с помощью примера
сравнение
Загрузки файлов часто содержат много непечатных символов (например, изображений), в то время как текстовые формы почти никогда не делают.
Из примеров мы видели, что:
application/x-www-form-urlencoded : имеет одну байтовую границу для каждого поля ( & ), но добавляет линейный коэффициент издержек в 3 раза для каждого непечатаемого символа.
Поэтому, даже если бы мы могли отправлять файлы с помощью application/x-www-form-urlencoded , мы бы этого не хотели, потому что это так неэффективно.
Но для печатных символов, найденных в текстовых полях, это не имеет значения и создает меньше накладных расходов, поэтому мы просто используем их.
@CiroSantilli 六四 事件 法轮功 纳米比亚 威 视 Я думаю, что этот ответ намного лучше, чем выбранный. Но, пожалуйста, удалите ненужный контент из своего профиля. Это против духа ТАК.
@smwikipedia спасибо за цитату RFC и за этот ответ! Об имени пользователя: для меня дух SO заключается в том, что каждый должен всегда иметь самую лучшую информацию. ~~ Давайте сохраним это обсуждение в твиттере или мета. Мир.
@KumarHarsh недостаточно подробно, чтобы ответить, я думаю. Пожалуйста, откройте новые супер подробные вопросы.
В приведенных ответах / примерах файл (скорее всего) загружен с HTML-формой или с использованием API-интерфейса FormData . Файл является только частью данных, отправляемых в запросе, отсюда и multipart/form-data Content-Type заголовок.
Если вы не (не хотите) использовать формы и заинтересованы только в загрузке одного файла, это самый простой способ включить ваш файл в запрос.
@wilt Если я не использую форму, но я хочу использовать API формданных, могу ли я сделать это таким образом?
@AnkitKhettry Похоже, что он загружен с формой или с помощью API формы. Эти «странные строки», на которые вы ссылаетесь, являются границами формы, обычно используемыми для разделения данных формы на части на сервере.
У меня есть этот пример кода Java:
и у меня есть этот файл test.html:
и, наконец, файл, который я буду использовать для тестирования с именем a.dat, имеет следующее содержимое:
если вы интерпретируете байты выше как символы ASCII или UTF-8, они фактически будут представлять:
Итак, давайте запустим наш Java-код, откроем test.html в нашем любимом браузере, загрузим a.dat и отправим форму и посмотрим, что получит наш сервер:
Ну, я не удивлен, увидев символы 9ie, потому что мы сказали Java печатать их, считая их символами UTF-8. Вы также можете прочитать их как необработанные байты.
С появлением управляемого приложения и веб-клиента некоторые задачи, которые решались в обычном приложением за несколько строчек, существенно усложнились. Казалось бы такая простая и часто используемая операция, как интерактивный выбор файла, которая в обычном приложении решалась в одном методе, теперь требует создания цепочки из нескольких процедур, которые вызываются одна за другой через ОписаниеОповещения. Вот как это было с использованием модальных вызовов:
Но как эту задачу решить на веб-клиенте? В поисковике не удалось найти готового универсального решения. Поискал в типовых, но там все разбросано по модулям и как-то запутано. Посмотрел пример в консоли СКД с диска ИТС для управляемых форм. Там тоже надо вычленять по кусочкам все шаги. Кроме того там применяется одна фича, которая позволяет открывать диалог выбора файла без установленного расширения работы с файлами. Но в общем случае эта хитрость не подойдет, так как она работает только для существующих файлов, насколько я понял. Поэтому написал процедуры, которые можно просто скопировать и использовать в будущем, не тратя время на то, чтобы вспоминать, как это работает.
Как генерировать примеры
Как только вы видите пример каждого метода, становится очевидным, как они работают, и когда вы должны использовать каждый из них.
Вы можете привести примеры, используя:
Сохраните форму в минимальный .html файл:
Создайте файлы для загрузки:
Запустите наш маленький эхо-сервер:
nc печатает полученный запрос
Проверено на: Ubuntu 14.04.3, nc BSD 1.105, Firefox 40.
Диалог выбора файла
Сразу приведу код, который получился после упрощения.
Я специально привел ранее вариант для обычных форм, чтобы проще было сравнивать. Код разбился на две примитивные процедуры и практически не изменился за счет метода ВыполнитьСценарийВыбораФайла(). Этот метод скрывает все рутинные асинхронные действия:
- подключает расширение по работе с файлами
- если расширение не подключено, то задает пользователю вопрос по его подключению
- начинает установку расширения, если пользователь подтвердит это действие
- открывает диалог выбора файла
- передает результаты выбора файла назад в прикладную процедуру КаталогНачалоВыбораЗавершение()
Далее приведу код этой служебной процедуры, написанной по принципу, из этой статьи.
То есть вместо того, чтобы писать несколько процедур с труднопонимаемыми названиями в стиле ЗагрузитьФайлКонсолиПослеПодключенияРасширенияПослеПомещенияФайла() , вся последовательность действий описана в одной. Кроме того, можно заметить, что она универсальная и не содержит зависимостей от контекста формы. То есть ее можно перенести в другую форму простым копированием
HTML5 ссылки
многочастному / форм-данных,
Для двоичного файла и текстового поля байты 61 CF 89 62 ( aωb в UTF-8) отправляются буквально. Вы можете проверить это с помощью nc -l localhost 8000 | hd , который говорит, что байты:
были отправлены ( 61 == 'a' и 62 == 'b').
Поэтому ясно, что:
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150 устанавливает тип содержимого multipart/form-data и говорит, что поля разделены заданной boundary строкой.
Но обратите внимание, что:
имеет на два меньше черт, -- чем фактический барьер
Это потому, что стандарт требует, чтобы граница начиналась с двух штрихов -- . Похоже, что другие черты - это то, как Firefox решил реализовать произвольную границу. RFC 7578 четко упоминает, что эти две лидирующие черты -- необходимы:
4.1. «Граничный» параметр multipart / form-data
Как и в случае других составных типов, части разделяются граничным разделителем, созданным с использованием CRLF, "-" и значения параметра "border".
каждое поле получает некоторые вложенные заголовки перед своими данными: Content-Disposition: form-data; , поле name , тем filename , за которым следуют данные.
Сервер читает данные до следующей граничной строки. Браузер должен выбрать границу, которая не будет отображаться ни в одном из полей, поэтому эта граница может варьироваться между запросами.
Поскольку у нас есть уникальная граница, кодирование данных не требуется: двоичные данные отправляются как есть.
ТОДО: каков оптимальный размер границы ( log(N) бьюсь об заклад) и название / время выполнения алгоритма, который его находит? На вопрос: /cs/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequence
Content-Type определяется автоматически браузером.
Как именно это определяется, было задано по адресу: Как браузер определяет тип mime загруженного файла?
Загрузка файлов с клиента на сервер
Постановка задачи: пусть требуется метод, который умеет помещать на сервер выбранный на клиенте файл. Если выбранный файл является каталогом, то необходимо поместить на сервер все файлы, содержащиеся в этом каталоге (подчиненные каталоги игнорировать).
Последовательность асинхронных действий:
- определить является ли файл каталогом
- если не является, то добавить его в массив помещаемых файлов
- если является, то найти все файлы этого каталога
- каждый из найденных файлов проверить является ли он каталогом. Если не является то добавить в массив помещаемых файлов (каждая итерация цикла обхода файлов является асинхронной, потому что вместо синхронного Файл.ЭтоФайл() необходимо использовать его аналог Файл.НачатьПроверкуЭтоФайл())
- поместить файлы на сервер
- вернуть результат помещения в прикладную процедуру, которая будет выполнять обработку файлов по какому-то алгоритму
Данная задача снова решается за три простых шага
Все детали скрыты в процедуре ВыполнитьСценарийЗагрузкиФайлаНаСервер(), которая подходит как для файлов, так и для каталогов. При необходимости ее можно доработать, чтобы она покрывала больше случаев.
Читайте также: