- XmlHttpRequest.onload не вызывается
- javascript — window.onload не запускается
- Это отлично работает
- 3 ответа
- Не могу получить ответ XMLHttpRequest
- объект XMLHttpRequest.события onload не вызывается
- 2 ответов
- XMLHttpRequest
- Основы
- Тип ответа
- Состояния запроса
- Отмена запроса
- Синхронные запросы
- HTTP-заголовки
- POST, FormData
- Прогресс отправки
- Запросы на другой источник
- Итого
XmlHttpRequest.onload не вызывается
Я играю с этой XmlHttpRequest штукой. В некоторых руководствах и книгах именно функция onload вызывается при выполнении запроса. В моем маленьком эксперименте эта функция никогда не вызывается. Вот мой код:
Я тестирую это в последнем выпуске Firefox (только что обновлен сегодня). Строка журнала в onload никогда не печатается, и точка останова, которую я установил в первой строке, никогда не достигается. Однако функция onreadystatechange вызывается дважды, и запрос http фактически выполняется. Вот что показывает консоль firebug:
В строке send есть ошибка. Я попытался изменить его на request.send() с идентичным результатом.
Сначала я подумал, что это может быть браузер, пытающийся предотвратить XSS, поэтому я переместил свою страницу драйвера html в экземпляр Tomcat на моем компьютере разработчика, но результат тот же.
Эта функция гарантированно будет вызвана? Как я уже говорил выше, это можно увидеть в большинстве учебных пособий, но с другой стороны, в W3C страница спецификации, фрагмент привет-мира использует onreadystatechange :
Он проверяет readyState == this.DONE . DONE имеет значение 4, что я вижу в своем журнале. Так что, если это была проблема, связанная с XSS, и браузер мешал мне установить соединение с другим доменом, тогда почему фактическое соединение установлено и получен статус DONE .
PS: Да, я знаю, что есть мощные библиотеки, которые легко это делают, но я все еще новичок в JavaScript, поэтому сначала хотел бы разобраться с низким уровнем.
UPDATE :
Я изменил URL на один внутри моего домена (localhost), и ошибка исчезла, но функция onload по-прежнему не вызывается. Проверено в IE8 и не работает. Проверено в Chrome и работает. Как это?
ОБНОВЛЕНИЕ 2:
Опробовано снова в Firefox, и теперь оно работает. Возможно, старая страница все еще была в кеше, поэтому я не сразу заметил это. По-прежнему не удается в IE8, я попытаюсь проверить его в более новой версии.
Источник
javascript — window.onload не запускается
То, что я пытаюсь сделать, это инструмент, в котором он будет экспортировать файл PDF.
Есть два случая:
- Мне не нужно ничего проверять, и сразу после того, как пользователь нажимает кнопку экспорта, он открывает новое пустое окно, потому что я использую заголовки для загрузки файла, а после завершения загрузки пустой страницы он закрывается.
Сценарий для случая 1
Это отлично работает
- Я должен проверить, есть ли доступный файл PDF для записи. перед открытием нового пустого окна, чтобы получить файл, а затем закрыть его, как в случае1
Сценарий для случая 2:
Теперь это не работает. На самом деле моя первая проблема заключалась в том, что он не делал новое окно, потому что оно рассматривает его как всплывающее окно, но я исправил это после часа исследований. Теперь закрытие окна — моя проблема.
Я уже искал это и все еще в настоящее время ищу не только здесь, но, к сожалению, я не смог найти ответ по этой проблеме. Любая помощь приветствуется.
Обновление . Для меня сработало использование XMLHttpRequest, чтобы мне не нужно было открывать новую пустую вкладку, чтобы мои php-заголовки служили мне файлом PDF.
Вот код, который я использую:
URL-адрес, который я использовал, был обработан контроллером, который дает мне pdf-файл с использованием заголовков php.
3 ответа
Блокировщики всплывающих окон обычно не допускают всплывающие окна (или программный щелчок по динамически создаваемым гиперссылкам и т. Д.), Если window.open() не вызывается прямым действием пользователя. Каждый браузер имеет немного другой механизм блокировки всплывающих окон.
В вашем случае 1 сначала весь код запускается в основном потоке в результате нажатия пользователем кнопки экспорта. Это отлично работает.
В случае 2 открытие окна может работать не во всех браузерах, поскольку оно вызывается из другого потока. Обработчик успеха Ajax будет вызываться асинхронно еще долго после завершения события onclick.
Чтобы исправить это, вы можете использовать синхронные запросы для выполнения всего кода в основном потоке. Вы можете XMLHttpRequest или опция асинхронности $.ajax(
Реализация приведенных выше предложений может помочь решить вашу проблему, поскольку window.onload() не запускается, но есть еще одно улучшение, которое можно внести — добавление обработчика onload перед навигацией:
Или даже лучше добавить его в основной теме, сразу после
Рассмотрите возможность использования iframe для этого. Это совершенно правильное решение, которое исключает необходимость прослушивания другого события окна, что является плохой практикой и не требуется.
Источник
Не могу получить ответ XMLHttpRequest
Такая вот проблемка возникла — отправляю пост запрос на сервер и нужно получить ответ. Запрос отправляется верно, но xhr.onload не срабатывает вообще.
Хорошо, пробую xhr.onreadystatechange — он срабатывает, но вместо ответа я получаю пустоту в алерт или null, если явно указываю, что формат ответа json(хотя он и так в таком формате).
xhr.status выдаёт 0
Но суть в том, что запрос отправляется верно и ответ с нужными данными приходит — это я вижу через сниффер HttpAnalyzer
Добавлено через 5 минут
Помощь в написании контрольных, курсовых и дипломных работ здесь.
XMLHttpRequest ждет ответ
Подскажите пожалуйста по такому вопросу. Делаю XMLHttpRequest запрос. Код примерно такой: .
XMLHttpRequest: не приходит ответ от сервера
Всем привет! В теле страницы имею это: 10
Попробуйте переменные var задавать.
Добавлено через 3 минуты
https://xmlhttprequest.ru/
Там же в зависимости от браузера перебираются все возможные(2-3) объекты и создается тот, который возможно.
Добавлено через 2 минуты
Сделайте как здесь
https://learn.javascript.ru/ajax-xmlhttprequest
В open GET, а не POST.
Именно этот материал читал, проблема в том конкретно, что запрос отправляется успешно и с заданными параметрами, но ответ не выводится и onload не отрабатывает. При том, что в сниффере видно ответ
Получаю «Готово!» и «0:»
Судя по этому, мы видим, что запрос завершен (readyState=4), статус запроса 0
Как это понимать-то?
Добавлено через 5 минут
Ещё момент непонятный для меня — мой запрос кроссдоменный. По идее он не должен выполняться, но он выполняется
Хорошо, я могу предположить, что запрос выполняется, но ответ не будет приниматься браузером, но ведь нет — этим же методом(только гет) я парсю курс биткоин с https://blockchain.info/ticker и всё отрабатывает успешно
Добавлено через 2 минуты
Самое обидное, что в сниффере я вижу все те данные ответа, которые мне нужны, а скрипт их не видит
Добавлено через 13 минут
Интересный момент — проблема с конкретным сайтом, этот же скрипт с другим сайтом отдает данные на ура.
Да, можно предположить, что какая-то защита на нем, но тогда бы ответ не был бы виден и снифферу, сервер тогда бы просто не отдавал данные.
Источник
объект XMLHttpRequest.события onload не вызывается
я играю с этим XmlHttpRequest вещь. В некоторых учебниках и книгах, это onload функция, вызываемая при выполнении запроса. В моем маленьком эксперименте, эта функция никогда не вызывается. Вот мой код:
Я тестирую это в последнем выпуске Firefox (только что обновленном сегодня). Строка журнала в onload никогда не печатается, и точка останова, которую я установил в первой строке, никогда не попадает. Однако onreadystatechange функция вызывается дважды, и HTTP запрос действительно сделан. Вот что показывает консоль firebug:
есть ошибка в блоке send линии. Я попытался изменить его на request.send() с идентичным результатом.
сначала я подумал, что это может быть браузер, пытающийся предотвратить XSS, поэтому я переместил свою страницу драйвера html в экземпляр Tomcat в моей машине dev, но результат тот же.
гарантируется ли вызов этой функции? Как я уже сказал выше, это часто можно увидеть в большинстве учебников, но с другой стороны в страница спецификации W3C, фрагмент hello world использует onreadystatechange вместо:
он проверяет readyState == this.DONE . DONE имеет значение 4, которое я вижу в своем журнале. Итак, если это была проблема, связанная с XSS, и браузер мешал мне установить соединение с другим доменом, то почему фактическое соединение выполнено и получен статус DONE.
PS: Да, я знаю, что есть мощные библиотеки, чтобы сделать это легко, но я все еще JavaScript noob, поэтому я хотел бы сначала понять низкий уровень.
обновление:
Я изменил URL-адрес на один внутри моего домена (localhost), и ошибка исчезла, но onload функция по-прежнему не вызывается. Проверено в IE8 и не работает. Протестировано в Chrome и работает. Как это?
обновление 2:
Снова проверил в Firefox, и теперь он работает. Вероятно, старая страница все еще была кэширована, поэтому я не мог ее заметить сейчас. Все еще не удается в IE8, я попытаюсь протестировать его в более новой версии.
2 ответов
похоже, что это действительно проблема XSS, и Firefox блокирует onload звонок. Я все еще не могу понять, почему сетевой запрос http фактически выполнялся и onreadystatechange был с DONE readyState.
Я изменил URL на другой в том же домене, и теперь он работает в Firefox (после некоторых ложных попыток, связанных с кэшем) и в Chrome. Он по-прежнему не работает в IE8, несмотря на официальные документы скажите, что он поддерживается. Я нашел это так ответ который утверждает обратное. Похоже на onload функция является более современным методом удобства, и старый способ проверки результата использует onreadystatechange вместо.
Я думаю, что я приму этот ответ в качестве решения, если не будет предоставлен более подробный ответ.
Источник
XMLHttpRequest
XMLHttpRequest – это встроенный в браузер объект, который даёт возможность делать HTTP-запросы к серверу без перезагрузки страницы.
Несмотря на наличие слова «XML» в названии, XMLHttpRequest может работать с любыми данными, а не только с XML. Мы можем загружать/скачивать файлы, отслеживать прогресс и многое другое.
На сегодняшний день не обязательно использовать XMLHttpRequest , так как существует другой, более современный метод fetch .
В современной веб-разработке XMLHttpRequest используется по трём причинам:
- По историческим причинам: существует много кода, использующего XMLHttpRequest , который нужно поддерживать.
- Необходимость поддерживать старые браузеры и нежелание использовать полифилы (например, чтобы уменьшить количество кода).
- Потребность в функциональности, которую fetch пока что не может предоставить, к примеру, отслеживание прогресса отправки на сервер.
Что-то из этого списка звучит знакомо? Если да, тогда вперёд, приятного знакомства с XMLHttpRequest . Если же нет, возможно, имеет смысл изучать сразу Fetch.
Основы
XMLHttpRequest имеет два режима работы: синхронный и асинхронный.
Сначала рассмотрим асинхронный, так как в большинстве случаев используется именно он.
Чтобы сделать запрос, нам нужно выполнить три шага:
Этот метод обычно вызывается сразу после new XMLHttpRequest . В него передаются основные параметры запроса:
- method – HTTP-метод. Обычно это «GET» или «POST» .
- URL – URL, куда отправляется запрос: строка, может быть и объект URL.
- async – если указать false , тогда запрос будет выполнен синхронно, это мы рассмотрим чуть позже.
- user , password – логин и пароль для базовой HTTP-авторизации (если требуется).
Заметим, что вызов open , вопреки своему названию, не открывает соединение. Он лишь конфигурирует запрос, но непосредственно отсылается запрос только лишь после вызова send .
Этот метод устанавливает соединение и отсылает запрос к серверу. Необязательный параметр body содержит тело запроса.
Некоторые типы запросов, такие как GET , не имеют тела. А некоторые, как, например, POST , используют body , чтобы отправлять данные на сервер. Мы позже увидим примеры.
Слушать события на xhr , чтобы получить ответ.
Три наиболее используемых события:
- load – происходит, когда получен какой-либо ответ, включая ответы с HTTP-ошибкой, например 404.
- error – когда запрос не может быть выполнен, например, нет соединения или невалидный URL.
- progress – происходит периодически во время загрузки ответа, сообщает о прогрессе.
Вот полный пример. Код ниже загружает /article/xmlhttprequest/example/load с сервера и сообщает о прогрессе:
После ответа сервера мы можем получить результат запроса в следующих свойствах xhr :
status Код состояния HTTP (число): 200 , 404 , 403 и так далее, может быть 0 в случае, если ошибка не связана с HTTP. statusText Сообщение о состоянии ответа HTTP (строка): обычно OK для 200 , Not Found для 404 , Forbidden для 403 , и так далее. response (в старом коде может встречаться как responseText ) Тело ответа сервера.
Мы можем также указать таймаут – промежуток времени, который мы готовы ждать ответ:
Если запрос не успевает выполниться в установленное время, то он прерывается, и происходит событие timeout .
Чтобы добавить к URL параметры, вида ?name=value , и корректно закодировать их, можно использовать объект URL:
Тип ответа
Мы можем использовать свойство xhr.responseType , чтобы указать ожидаемый тип ответа:
- «» (по умолчанию) – строка,
- «text» – строка,
- «arraybuffer» – ArrayBuffer (для бинарных данных, смотрите в ArrayBuffer, бинарные массивы),
- «blob» – Blob (для бинарных данных, смотрите в Blob),
- «document» – XML-документ (может использовать XPath и другие XML-методы),
- «json» – JSON (парсится автоматически).
К примеру, давайте получим ответ в формате JSON:
В старом коде вы можете встретить свойства xhr.responseText и даже xhr.responseXML .
Они существуют по историческим причинам, раньше с их помощью получали строки или XML-документы. Сегодня следует устанавливать желаемый тип объекта в xhr.responseType и получать xhr.response , как показано выше.
Состояния запроса
У XMLHttpRequest есть состояния, которые меняются по мере выполнения запроса. Текущее состояние можно посмотреть в свойстве xhr.readyState .
Список всех состояний, указанных в спецификации:
Состояния объекта XMLHttpRequest меняются в таком порядке: 0 → 1 → 2 → 3 → … → 3 → 4 . Состояние 3 повторяется каждый раз, когда получена часть данных.
Изменения в состоянии объекта запроса генерируют событие readystatechange :
Вы можете наткнуться на обработчики события readystatechange в очень старом коде, так уж сложилось исторически, когда-то не было событий load и других. Сегодня из-за существования событий load/error/progress можно сказать, что событие readystatechange «морально устарело».
Отмена запроса
Если мы передумали делать запрос, можно отменить его вызовом xhr.abort() :
При этом генерируется событие abort , а xhr.status устанавливается в 0 .
Синхронные запросы
Если в методе open третий параметр async установлен на false , запрос выполняется синхронно.
Другими словами, выполнение JavaScript останавливается на send() и возобновляется после получения ответа. Так ведут себя, например, функции alert или prompt .
Вот переписанный пример с параметром async , равным false :
Выглядит, может быть, и неплохо, но синхронные запросы используются редко, так как они блокируют выполнение JavaScript до тех пор, пока загрузка не завершена. В некоторых браузерах нельзя прокручивать страницу, пока идёт синхронный запрос. Ну а если же синхронный запрос по какой-то причине выполняется слишком долго, браузер предложит закрыть «зависшую» страницу.
Многие продвинутые возможности XMLHttpRequest , такие как выполнение запроса на другой домен или установка таймаута, недоступны для синхронных запросов. Также, как вы могли заметить, ни о какой индикации прогресса речь тут не идёт.
Из-за всего этого синхронные запросы используют очень редко. Мы более не будем рассматривать их.
HTTP-заголовки
XMLHttpRequest умеет как указывать свои заголовки в запросе, так и читать присланные в ответ.
Для работы с HTTP-заголовками есть 3 метода:
Устанавливает заголовок запроса с именем name и значением value .
Некоторые заголовки управляются исключительно браузером, например Referer или Host , а также ряд других. Полный список тут.
XMLHttpRequest не разрешено изменять их ради безопасности пользователей и для обеспечения корректности HTTP-запроса.
Ещё одной особенностью XMLHttpRequest является то, что отменить setRequestHeader невозможно.
Если заголовок определён, то его нельзя снять. Повторные вызовы лишь добавляют информацию к заголовку, а не перезаписывают его.
Возвращает значение заголовка ответа name (кроме Set-Cookie и Set-Cookie2 ).
Возвращает все заголовки ответа, кроме Set-Cookie и Set-Cookie2 .
Заголовки возвращаются в виде единой строки, например:
Между заголовками всегда стоит перевод строки в два символа «\r\n» (независимо от ОС), так что мы можем легко разделить их на отдельные заголовки. Значение заголовка всегда отделено двоеточием с пробелом «: » . Этот формат задан стандартом.
Таким образом, если хочется получить объект с парами заголовок-значение, нам нужно задействовать немного JS.
Вот так (предполагается, что если два заголовка имеют одинаковое имя, то последний перезаписывает предыдущий):
POST, FormData
Чтобы сделать POST-запрос, мы можем использовать встроенный объект FormData.
Обычно форма отсылается в кодировке multipart/form-data .
Если нам больше нравится формат JSON, то используем JSON.stringify и отправляем данные как строку.
Важно не забыть поставить соответствующий заголовок Content-Type: application/json , многие серверные фреймворки автоматически декодируют JSON при его наличии:
Метод .send(body) весьма всеяден. Он может отправить практически что угодно в body , включая объекты типа Blob и BufferSource .
Прогресс отправки
Событие progress срабатывает только на стадии загрузки ответа с сервера.
А именно: если мы отправляем что-то через POST -запрос, XMLHttpRequest сперва отправит наши данные (тело запроса) на сервер, а потом загрузит ответ сервера. И событие progress будет срабатывать только во время загрузки ответа.
Если мы отправляем что-то большое, то нас гораздо больше интересует прогресс отправки данных на сервер. Но xhr.onprogress тут не поможет.
Существует другой объект, без методов, только для отслеживания событий отправки: xhr.upload .
Он генерирует события, похожие на события xhr , но только во время отправки данных на сервер:
- loadstart – начало загрузки данных.
- progress – генерируется периодически во время отправки на сервер.
- abort – загрузка прервана.
- error – ошибка, не связанная с HTTP.
- load – загрузка успешно завершена.
- timeout – вышло время, отведённое на загрузку (при установленном свойстве timeout ).
- loadend – загрузка завершена, вне зависимости от того, как – успешно или нет.
Примеры обработчиков для этих событий:
Пример из реальной жизни: загрузка файла на сервер с индикацией прогресса:
Запросы на другой источник
XMLHttpRequest может осуществлять запросы на другие сайты, используя ту же политику CORS, что и fetch.
Точно так же, как и при работе с fetch , по умолчанию на другой источник не отсылаются куки и заголовки HTTP-авторизации. Чтобы это изменить, установите xhr.withCredentials в true :
Детали по заголовкам, которые при этом необходимы, смотрите в главе fetch.
Итого
Типичный код GET-запроса с использованием XMLHttpRequest :
Событий на самом деле больше, в современной спецификации они все перечислены в том порядке, в каком генерируются во время запроса:
- loadstart – начало запроса.
- progress – прибыла часть данных ответа, тело ответа полностью на данный момент можно получить из свойства responseText .
- abort – запрос был прерван вызовом xhr.abort() .
- error – произошла ошибка соединения, например неправильное доменное имя. Событие не генерируется для HTTP-ошибок как, например, 404.
- load – запрос успешно завершён.
- timeout – запрос был отменён по причине истечения отведённого для него времени (происходит, только если был установлен таймаут).
- loadend – срабатывает после load , error , timeout или abort .
События error , abort , timeout и load взаимно исключают друг друга – может произойти только одно из них.
Наиболее часто используют события завершения загрузки ( load ), ошибки загрузки ( error ), или мы можем использовать единый обработчик loadend для всего и смотреть в свойствах объекта запроса xhr детали произошедшего.
Также мы уже видели событие: readystatechange . Исторически оно появилось одним из первых, даже раньше, чем была составлена спецификация. Сегодня нет необходимости использовать его, так как оно может быть заменено современными событиями, но на него можно часто наткнуться в старом коде.
Источник