Ajax

Options

Note that headers cannot be set on an XDomainRequest instance.

Specify whether this is a synchrounous request. Note that when
this is true the callback will be called synchronously. In
most cases this option should not be used. Only use if you
know what you are doing!

If is , then this must be a JSON-serializable object. is passed to and sent.

Number of miliseconds to wait for response. Defaults to 0 (no timeout). Ignored when is true.

Set to to send request as (see ) and parse response from JSON.

For backwards compatibility can also be a valid JSON-serializable value to be sent to the server. Additionally the response body is still parsed as JSON

For sending booleans as JSON body see FAQ

A wildcard cannot be used in the header when is true.
The header needs to specify your origin explicitly or browser will abort the request.

A function being called right before the method of the or instance is called. The or instance is passed as an argument.

Pass an object (or something that acts like one) to use instead of constructing a new one using the or constructors. Useful for testing.

GET и POST-запросы. Кодировка.

Во время обычного submit’а формы браузер сам кодирует значения полей и составляет тело GET/POST-запроса для посылки на сервер. При работе через XmlHttpRequest, это нужно делать самим, в javascript-коде. Большинство проблем и вопросов здесь связано с непониманием, где и какое кодирование нужно осуществлять.

Вначале рассмотрим общее кодирование запросов, ниже — правильную работу с русским языком для windows-1251.

Существуют два вида кодирования HTTP-запроса. Основной — urlencoded, он же — стандартное кодирование URL. Пробел представляется как %20, русские буквы и большинство спецсимволов кодируются, английские буквы и дефис оставляются как есть.

Способ, которым следует кодировать данные формы при submit’е, задается в ее HTML-таге:

<form method="get"> // метод GET с кодировкой по умолчанию
<form method="post" enctype="application/x-www-form-urlencoded"> // enctype явно задает кодировку
<form method="post"> // метод POST с кодировкой по умолчанию (urlencoded, как и предыдущая форма)

Если форма submit’ится обычным образом, то браузер сам кодирует (urlencode) название и значение каждого поля данных ( и т.п.) и отсылает форму на сервер в закодированном виде.

Формируя XmlHttpRequest, мы должны формировать запрос «руками», кодируя поля функцией .

Конечно, пропускать через encodeURIComponent стоит только те переменные, в которых могут быть спецсимволы или не английские буквы, т.е которые и будут как раз закодированы.

Например, для посылки GET-запроса с произвольными параметрами name и surname, их необходимо закодировать вот так:

// Пример с GET
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("GET", '/script.html?'+params, true)
...
xmlhttp.send(null)

В методе POST параметры передаются не в URL, а в теле, посылаемом через . Поэтому нужно указывать не в адресе, а при вызове

Кроме того, при POST обязателен заголовок Content-Type, содержащий кодировку. Это указание для сервера — как обрабатывать (раскодировать) пришедший запрос.

// Пример с POST
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("POST", '/script.html', true)
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
...
xmlhttp.send(params)

Заголовки Content-Length, Connection в POST-запросах, хотя их и содержат некоторые «руководства», обычно не нужны. Используйте их, только если Вы действительно знаете, что делаете.

Запросы multipart/form-data

Второй способ кодирования — это отсутствие кодирования. Например, кодировать не нужно для пересылки файлов. Он указывается в форме (только для POST) так:

<form method="post" enctype="multipart/form-data">

В этом случае при отправке данных на сервер ничего не кодируется. А сервер, со своей стороны, посмотрев на Content-Type(=multipart/form-data), поймет, что пришло.

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

Кодировка (языковая)

Если Вы используете только UTF-8 — пропустите эту секцию.

Все идущие на сервер параметры GET/POST, кроме случая multipart/form-data, кодируются в UTF-8. Не в кодировке страницы, а именно в UTF-8. Поэтому, например, в PHP их нужно при необходимости перекодировать функцией iconv.

<?php
// ajax.php
$name = iconv('UTF8','CP1251',$_GET);
?>

С другой стороны, ответ с сервера браузер воспринимает именно в той кодировке, которая указана в заголовке ответа Content-Type. Т.е, опять же, в PHP, чтобы браузер воспринял ответ в windows-1251 и нормально отобразил данные на странице в windows-1251,
нужно послать заголовок с кодировкой в php-коде, например так:

<?php
// ajax.php
header('Content-Type: text/plain; charset=utf-8');
?>

Или же, такой заголовок должен добавить сервер. Например, в apache автоматически добавляется кодировка опцией:

# в конфиге апача
AddDefaultCharset windows-1251

Событие onprogress в деталях

При обработке события есть ряд важных тонкостей.

Можно, конечно, их игнорировать, но лучше бы знать.

Заметим, что событие, возникающее при , имеет одинаковый вид на стадии отправки (в обработчике ) и при получении ответа (в обработчике ).

Оно представляет собой объект типа со свойствами:

Сколько байт уже переслано.

Имеется в виду только тело запроса, заголовки не учитываются.

Если , то известно полное количество байт для пересылки, и оно хранится в свойстве .

Общее количество байт для пересылки, если известно.

А может ли оно быть неизвестно?

  • При отправке на сервер браузер всегда знает полный размер пересылаемых данных, так что всегда содержит конкретное количество байт, а значение всегда будет .
  • При скачивании данных – обычно сервер в начале сообщает их общее количество в HTTP-заголовке . Но он может и не делать этого, например если сам не знает, сколько данных будет или если генерирует их динамически. Тогда будет равно . А чтобы отличить нулевой размер данных от неизвестного – как раз служит , которое в данном случае равно .

Ещё особенности, которые необходимо учитывать при использовании :

Событие происходит при каждом полученном/отправленном байте, но не чаще чем раз в 50 мс.
Это обозначено в .

В процессе получения данных, ещё до их полной передачи, доступен , но он не обязательно содержит корректную строку.
Можно до окончания запроса заглянуть в него и прочитать текущие полученные данные

Важно, что при пересылке строки в кодировке UTF-8 кириллические символы, как, впрочем, и многие другие, кодируются 2 байтами. Возможно, что в конце одного пакета данных окажется первая половинка символа, а в начале следующего – вторая

Поэтому полагаться на то, что до окончания запроса в находится корректная строка нельзя. Она может быть обрезана посередине символа.
Исключение – заведомо однобайтные символы, например цифры или латиница.

Сработавшее событие не гарантирует, что данные дошли.
Событие срабатывает, когда данные отправлены браузером. Но оно не гарантирует, что сервер получил, обработал и записал данные на диск. Он говорит лишь о самом факте отправки.
Поэтому прогресс-индикатор, получаемый при его помощи, носит приблизительный и оптимистичный характер.

See also

  • MDN articles about XMLHttpRequest:
    • AJAX — Getting Started
    • Using XMLHttpRequest
    • HTML in XMLHttpRequest
  • XMLHttpRequest references from W3C and browser vendors:
    • W3C: XMLHttpRequest (base features)
    • W3C: XMLHttpRequest (latest editor’s draft with extensions to the base functionality, formerly XMLHttpRequest Level 2
    • Microsoft documentation
  • «Using the XMLHttpRequest Object» (jibbering.com)
  • XMLHttpRequest — REST and the Rich User Experience
  • HTML5 Rocks — New Tricks in XMLHttpRequest2
  • Thread on the naming convention of
  • — how to access from JSM modules etc which do not have access to DOM

    • Components.utils.importGlobalProperties
    • nsIXMLHttpRequest

基本

XMLHttpRequest には2つの操作モードがあります: 同期と非同期です。

先に、ほとんどのケースで使われる非同期を見ていきましょう。

リクエストをするためには、次の3ステップが必要です:

  1. を作成します:

  2. 初期化をします:

    このメソッドは通常 のすぐ後で呼ばれ、リクエストのメインのパラメータを指定します。:

    • – HTTPメソッド. たいてい か です.
    • – リクエストURL。文字列で、URL オブジェクトもOKです。
    • – 明示的に が指定されている場合、リクエストは同期になります。これについては後ほど説明します。
    • , – ベーシック HTTP 認証のユーザとパスワードです(必要に応じて).

    呼び出しに注意してください。その名前とは対照的に、接続をオープンするわけではありません。リクエストを設定するだけで、ネットワーク処理は 呼び出しでのみ始まります。

  3. それを送ります

    このメソッドは接続をオープンし、リクエストをサーバに送信します。オプションの パラメータにはリクエストボディが含まれます。

    のようないくつかのリクエストメソッドは body を持ちません。また などはデータをサーバに送信するのに を使います。後ほど例を見ていきます。

  4. 応答に対するイベントをリッスンします

    これら3つがもっとも広く使われています:

    • – 結果が準備できたとき。404 のような HTTP エラーを含みます。
    • – リクエストが送信できなかったとき e.g. ネットワークダウン or URL不正
    • – ダウンロード中に定期的にトリガーされ、ダウンロードされた量が確認できます。

これは完全な例です。下のコードはサーバから のURLをロードし、進行状況を表示します。:

サーバーが応答すると、リクエストオブジェクトの次のプロパティで結果を受け取ることができます。:

HTTPステータスコード(数値): , , など。HTTP 以外の失敗の場合は になります。

:HTTPステータスメッセージ(文字列): 通常, の場合は 、 の場合は 、 の場合は など。

(古いスクリプトはを使用する場合があります)
:サーバーのレスポンス。

対応するプロパティを使用してタイムアウトを指定することもできます。:

リクエストが指定時間内で成功しない場合はキャンセルされ、 イベントが発生します。

URL 検索パラメータ

のような URL パラメータを渡しつつ、適切なエンコーディングを保証するには、URL オブジェクトが使えます。:

Функции обратного вызова

  • Выполняется запрос для получения репозиториев пользователя (в данном случае я загружаю собственные репозитории);
  • После завершения запроса вызывается коллбэк ;
  • Если не было ошибок, разбираем ответ сервера c помощью J, преобразовываем его, для удобства, в объект;
  • После этого перебираем список пользователей, так как в нём может быть больше одного элемента, и для каждого из них запрашиваем список репозиториев, используя URL, возвращённый для каждого пользователя после выполнения первого запроса. Подразумевается, что — это URL для наших следующих запросов, и получили мы его из первого запроса.
  • Когда запрос, направленный на загрузку данных о репозиториях, завершён, вызывается коллбэк, теперь это . Здесь, так же как и при загрузке списка пользователей, можно обработать ошибки или полезные данные, в которых содержится список репозиториев пользователя.

Ад коллбэков во всей красе. Изображение взято отсюда.

Частые проблемы¶

Кеширование

Многие браузеры поддерживают кеширование ответов на XmlHttpRequest запросы. При этом реализации кеширования немного разные.

Например, при повторном XmlHttpRequest на тот же URL, Firefox посылает запрос с заголовком «» со значением, указанным в заголовке «» предыдущего ответа.

А Internet Explorer делает так, только когда кешированный ответ устарел, т. е. после времени из заголовка «Expires» предыдущего ответа. Поэтому, кстати, многие думают, что Internet Explorer вообще не очищает кеш ответов.

Самое простое решение проблемы — просто убрать кеширование. Например, при помощи заголовков, или добавлением случайного параметра в URL типа:

Есть, однако, ряд случаев, когда кеширование XMLHttpRequest браузером полезно, улучшает время ответа и экономит трафик.

Пример демонстрирует универсальный код работы с кешем для Internet Explorer и Firefox.

В Internet Explorer, если запрос возвращается из кеша без перепроверки, заголовок — пустая строка. Поэтому нужно сделать дополнительный запрос, который на самом деле никакой не дополнительный, т. к. текущий возвращен из кеша.

Ссылку на кешированый запрос сохраняем, т. к. если код ответа дополнительного запроса — «», то его тело станет пустой строкой («»), и нужно будет вернуться к кешированному объекту. Более эффективным, впрочем, будет не создавать новый объект , а сохранить данные из существующего и использовать заново его же.

Пример выше опирается на то, что сервер всегда выдает заголовок «», что верно для большинства конфигураций. В нем делается синхронный запрос. В асинхронном случае, проверка на Date и т. д. нужно делать после получения ответа в функции-обработчике .

Повторное использование объекта XmlHttpRequest

В Internet Explorer, если вызван после установки , может быть проблема с повторным использованием этого XmlHttpRequest.

Чтобы использовать заново XmlHttpRequest, сначала вызывайте метод , а затем — присваивайте . Это нужно потому, что IE неявно очищает объект XmlHttpRequest в методе , если его статус «».

Вызывать для перенаправления запроса на другой URL не нужно, даже если текущий запрос еще не завершился.

Утечки памяти

В Internet Explorer объект XmlHttpRequest принадлежит миру DOM/COM, а Javascript-функция — миру Javascript. Вызов r неявную круговую связь: ссылается на функцию через , а функция, через область видимости — видит (ссылается на) .

Невозможность обнаружить и оборвать такую связь во многих (до IE 6,7 редакции июня 2007?) версиях Internet Explorer приводит к тому, что XmlHttpRequest вместе с ответом сервера, функция-обработчик, и всё замыкание прочно оседают в памяти до перезагрузки браузера.

Чтобы этого избежать, ряд фреймворков (YUI, dojo…) вообще не ставят , а вместо этого через проверяют его каждые 10 миллисекунд. Это разрывает круговую связку <-> , и утечка памяти не грозит даже в самых глючных браузерах.

Промисы

  • Промис инициализируется с помощью функции, в которой есть вызовы методов и ;
  • Асинхронный код помещают внутри функции, созданной с помощью конструктора . Если код будет выполнен успешно, вызывают метод , если нет — ;
  • Если функция вызовет , будет исполнен метод для объекта , аналогично, если будет вызван , будет исполнен метод .
  • Методы и принимают только один параметр, в результате, например, при выполнении команды вида, коллбэку будет передано лишь ;
  • Если объединить в цепочку несколько вызовов , в конце соответствующих коллбэков следует всегда использовать , иначе все они будут выполнены одновременно, а это, очевидно, не то, чего вы хотите достичь;
  • При выполнении команды , если следующим в цепочке идёт , он будет выполнен (вы можете считать выражением, которое выполняется в любом случае);
  • Если в цепочке из вызовов в каком-то из них возникнет ошибка, следующие за ним будут пропущены до тех пор, пока не будет найдено выражение ;
  • У промисов есть три состояния: «pending» — состояние ожидания вызова или , а также состояния «resolved» и «rejected», которые соответствуют успешному, с вызовом , и неуспешному, с вызовом , завершению работы промиса. Когда промис оказывается в состоянии «resolved» или «rejected», оно уже не может быть изменено.

Это — промис в состоянии ожидания. Он может быть либо успешно разрешён, либо отклонён

материал

Introduction

XMLHttpRequest (XHR) is a browser-level API that enables the client to
script data transfers via JavaScript. XHR made its first debut in
Internet Explorer 5, became one of the key technologies behind the
Asynchronous JavaScript and XML (AJAX) revolution, and is now a
fundamental building block of nearly every modern web application.

Prior to XHR, the web page had to be refreshed to send or fetch any
state updates between the client and server. With XHR, this workflow
could be done asynchronously and under full control of the application
JavaScript code. XHR is what enabled us to make the leap from building
pages to building interactive web applications in the browser.

However, the power of XHR is not only that it enabled asynchronous
communication within the browser, but also that it made it simple. XHR is
an application API provided by the browser, which is to say that the
browser automatically takes care of all the low-level connection
management, protocol negotiation, formatting of HTTP requests, and much
more:

  • The browser manages connection establishment, pooling, and
    termination.

  • The browser determines the best HTTP(S) transport (HTTP/1.0, 1.1,
    2).

  • The browser handles HTTP caching, redirects, and content-type
    negotiation.

  • The browser enforces security, authentication, and privacy
    constraints.

  • And more…

Free from worrying about all the low-level details, our applications
can focus on the business logic of initiating requests, managing their
progress, and processing returned data from the server. The combination
of a simple API and its ubiquitous availability across all the browsers
makes XHR the «Swiss Army knife» of networking in the browser.

As a result, nearly every networking use case (scripted downloads,
uploads, streaming, and even real-time notifications) can and have been
built on top of XHR. Of course, this doesn’t mean that XHR is the most
efficient transport in each case—in fact, as we will see, far from it—but
it is nonetheless often used as a fallback transport for older clients,
which may not have access to newer browser networking APIs. With that in
mind, let’s take a closer look at the latest capabilities of XHR, its use
cases, and performance do’s and don’ts.

4 ответа

Лучший ответ

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

Это способ установить заголовки запроса. Аргументы, которые вы видите

1) настраиваемый заголовок (в данном случае Content-type ) 2) значение заголовка. (в этом случае x-www-form-urlencoded )

20

hvgotcodes
16 Янв 2012 в 16:02

Он устанавливает HTTP-заголовок Content-type для хранения данных в кодировке url, отправленных из формы.

JanL
16 Янв 2012 в 16:03

Это именно то, что он говорит. Он установит информацию «заголовка» для следующего .

Заголовок — это в значительной степени пара ключ / значение. Он используется для передачи метаинформации на целевой сервер для текущего запроса. В вашем конкретном случае он используется, чтобы сообщить серверу, какой тип контента используется для этого запроса.

3

jAndy
16 Янв 2012 в 16:04

HTTP-запросы — это сообщения, передаваемые из одной компьютерной системы в другую в соответствии с установленной процедурой («протокол» — здесь H yper T ext T перевод) P rotocol), чтобы делать такие вещи, как отправка данных, запрос данных для отправки обратно, обновление ранее отправленных данных и т. д.

Заголовок — это, по сути, фрагмент информации о данных в теле HTTP-запроса. Его цель — сообщить машине, получающей запрос, какой тип данных заключен в теле запроса, его форматировании, используемом языке, для установки файла cookie, дате, хост-машине и т. Д.

В HTTP-запрос может быть помещено более одного заголовка, и каждый заголовок имеет компонент «имя» и «значение». На веб-страницах они выглядят как

И вы найдете их чуть ниже верхней части веб-страницы внутри элемента.

Чтобы позволить людям отправлять HTTP-запросы из функции JavaScript, мы создаем новый объект XMLHttpRequest, так же как ваш код делает это с

К этому новому пустому объекту вы намереваетесь добавить данные. Несмотря на свое название, XMLHttpRequest также позволяет отправлять данные в нескольких форматах, отличных от XML, например HTML-код, текст, JSON и т. Д. В вашем примере каждое имя данных будет отделено от его значения символом «=», а каждая пара данных / значений будет отделена от следующей пары символом «&». Этот вид форматирования известен как кодирование URL.

Мы должны сообщить принимающему компьютеру, как кодируются данные в теле HTTP-запроса. Для этого существует , который добавляется в запрос с помощью метода. setRequestHeader (.. ) . Этот метод использует 2 параметра: имя заголовка и значение заголовка. Вся эта операция достигается в линии

Этот метод setRequestHeader (..) должен быть применен к запросу после того, как запрос характеризуется методом open (…) , но before : окончательный запрос отправляется методом send (.) .

Метод open (…) определяет: (1) тип HTTP-запроса, например, GET / POST / PUT и т.д .; (2) веб-страница, которая содержит сценарий обработки для этого запроса, например, некоторый .php файл или конечная точка запроса Node.js, которая делает соответствующий запрос к внутренней базе данных; и (3) характер динамики запроса, например, асинхронным запросам присваивается значение «истина», синхронным запросам присваивается «ложь».

Метод send (.) присоединяет данные для отправки в теле запроса, в вашем случае это переменная с именем ‘parameters’.

На ваш более широкий вопрос о том, в каких ситуациях используется setRequestHeader (..) , я бы сказал, что он используется в большинстве ситуаций HTTP-запросов. Но добавлены в тело HTTP-запрос вызывает настройку по умолчанию для заголовка «Content-Type».

3

Trunk
31 Янв 2020 в 15:54

§Monitoring Download and Upload Progress

Network connectivity can be intermittent, and latency and bandwidth
are highly variable. So how do we know if an XHR request has succeeded,
timed out, or failed? The XHR object provides a convenient API for
listening to progress events (), which indicate the current status
of the request.

Event type Description

Times fired

loadstart Transfer has begun

once

progress Transfer is in progress

zero or more

error Transfer has failed

zero or once

abort Transfer is terminated

zero or once

load Transfer is successful

zero or once

loadend Transfer has finished once

Table 15-1. XHR progress events

Each XHR transfer begins with a loadstart and finishes with a
loadend event, and in between, one or more additional events are
fired to indicate the status of the transfer. Hence, to monitor progress
the application can register a set of JavaScript event listeners on the
XHR object:

var xhr = new XMLHttpRequest();
xhr.open('GET','/resource');
xhr.timeout = 5000; 

xhr.addEventListener('load', function() { ... }); 
xhr.addEventListener('error', function() { ... }); 

var onProgressHandler = function(event) {
  if(event.lengthComputable) {
    var progress = (event.loaded / event.total) * 100; 
    ...
  }
}

xhr.upload.addEventListener('progress', onProgressHandler); 
xhr.addEventListener('progress', onProgressHandler); 
xhr.send();
  1. Set request timeout to 5,000 ms (default: no timeout)

  2. Register callback for successful request

  3. Register callback for failed request

  4. Compute transfer progress

  5. Register callback for upload progress events

  6. Register callback for download progress events

Either the load or error event will fire once to
indicate the final status of the XHR transfer, whereas the
progress event can fire any number of times and provides a
convenient API for tracking transfer status: we can compare the
loaded attribute against total to estimate the amount
of transferred data.

§XHR Use Cases and Performance

XMLHttpRequest is what enabled us to make the leap from building pages
to building interactive web applications in the browser. First, it
enabled asynchronous communication within the browser, but just as
importantly, it also made the process simple. Dispatching and controlling
a scripted HTTP request takes just a few lines of JavaScript code, and
the browser handles all the rest:

  • Browser formats the HTTP request and parses the response.

  • Browser enforces relevant security (same-origin) policies.

  • Browser handles content negotiation (e.g., gzip).

  • Browser handles request and response caching.

  • Browser handles authentication, redirects, and more…

As such, XHR is a versatile and a high-performance transport for any
transfers that follow the HTTP request-response cycle. Need to fetch a
resource that requires authentication, should be compressed while in
transfer, and should be cached for future lookups? The browser takes care
of all of this and more, allowing us to focus on the application logic!

However, XHR also has its limitations. As we saw, streaming has never
been an official use case in the XHR standard, and the support is
limited: streaming with XHR is neither efficient nor convenient.
Different browsers have different behaviors, and efficient binary
streaming is impossible. In short, XHR is not a good fit for streaming.

Similarly, there is no one best strategy for delivering real-time
updates with XHR. Periodic polling incurs high overhead and message
latency delays. Long-polling delivers low latency but still has the same
per-message overhead; each message is its own HTTP request. To have both
low latency and low overhead, we need XHR streaming!

As a result, while XHR is a popular mechanism for «real-time»
delivery, it may not be the best-performing transport for the job. Modern
browsers support both simpler and more efficient options, such as
Server-Sent Events and WebSocket. Hence, unless you have a specific
reason why XHR polling is required, use them.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector