Примечание редактора: Помимо интерфейса Chuangyu и блога автора, эта статья также опубликована в Yuque.
Примечание редактора: Автор также находится в Наггетс, прошу обратить внимание:@GoDotDotDot
предисловие
В этой статье в основном говорится оFetchНекоторые базовые знания и то, как мы их используем в производственной разработке. Чтобы лучше понятьFetch, мы надеемся, что у вас есть некоторое понимание следующих моментов знаний.Если у вас есть соответствующий опыт разработки, это лучше всего.
Некоторые ключевые слова оснащены соответствующими ссылками в этой статье. Если вы не знаете достаточно о ключевых слов или хотите узнать больше, вы можете обогатить себя, нажав на него. Некоторые точки знаний в текстеMDN FetchОна написана очень подробно, поэтому я ее пропущу, надеюсь, что студенты смогут читать ее параллельно при чтении этой статьи.
Идея этой статьи исходит изТехнические характеристикиДля начала, цель состоит в том, чтобы дать всем понять более тщательно, чтобы знать, что это такое и почему это.
для лучшего контроляFetch, в статье также приведены некоторыеобразец кодаДля всех, чтобы изучить и использовать. Прежде чем использовать этот пример кода, мы надеемся, что выnode.js Имейте некоторое понимание, если нет, вы можете завершить свое обучение, следуя дружеским советам в примере.
Прочитав эту статью, вы будете знать следующее:
- чтоFetch
- Fetchнекоторые основные понятия о
- как использоватьFetch
- FetchНекоторые недостатки и как мы «элегантно» это используем
Надеюсь, после прочтения этой статьи вы получили базовое представление о Fetch.
Введение в выборку
Fetchэто новая технология получения ресурсов, она используется для замены технологии, на которую мы давно жалуемся (XHR).
FetchОн прост в использовании, он возвращаетPromise, даже если у вас нетXHRОпыт разработки также можно быстро начать. Сказав все это, давайте взглянем на пример кода ниже.
fetch('https://github.com/frontend9/fe9-library', {
method: 'get'
}).then(function(response) {
}).catch(function(err) {
// Error
});
Нельзя ли проще? Ну, так как мыFetchПосле того, как у нас есть простое понимание, давайте разберемсяFetchосновная концепция.
Получить основные понятия
существуетFetchЕсть четыре основных понятия, ониHeaders,Request,Responseа такжеBody. для лучшего пониманияFetch, нам нужно краткое понимание этих понятий.
в полномHTTPПо запросу эти четыре концепции уже включены. Запросы имеют запрос в заголовки и запрос органам, а ответы имеют ответы заголовки и ответные органы. Так что нам нужно понять эти концепции.
Headers
Для достижения гибкости головы головка может быть изменена, является очень важным возможностями. Заголовки принадлежатHTTPсерединастолицаЧасть , это абстрактный интерфейс, который можно использовать дляHTTPдобавлять, изменять и удалять заголовки запросов и ответов.
Давайте посмотрим, какие у него есть интерфейсы:
typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) HeadersInit;
[Constructor(optional HeadersInit init),
Exposed=(Window,Worker)]
interface Headers {
void append(ByteString name, ByteString value);
void delete(ByteString name);
ByteString? get(ByteString name);
boolean has(ByteString name);
void set(ByteString name, ByteString value);
iterable<ByteString, ByteString>;
};interface Headers {
void append(ByteString name, ByteString value);
void delete(ByteString name);
ByteString? get(ByteString name);
boolean has(ByteString name);
void set(ByteString name, ByteString value);
iterable<ByteString, ByteString>;
};
// 来自 https://fetch.spec.whatwg.org/#headers-class
Интерфейс, определенный в спецификации, может соответствоватьMDNдля просмотра вы можете нажатьздесьДавайте более интуитивно посмотрим, какие методы он может нам использовать.
Здесь у нас естьHeaders
объяснить параметры конструкции. Первый тип параметраHeadersInit
, давайте посмотрим, какие типы значений поддерживает этот тип. Определения, которые мы можем видеть из спецификации:
typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) HeadersInit;
Здесь мы соответствуемJavaScript
Этот язык означает, что объект может быть массивом или парой ключа (то есть объекты). О том, как инициализировать эти параметры, мы можем выглядеть определенным в спецификацииобработать.
To fill a
Headers
object (headers) with a given object (object), run these steps:
Здесь мне нужно объяснить это, и использование выборки будет включать в себя немного и то, что мы видимpolyfillпоможет.
- Первый: массив, когда каждый элемент данных не содержит двух элементов, сразу будет выброшена ошибка. Тогда первый элемент массива
header
имя, а второй элемент — значение. , и, наконец, непосредственно черезappend
добавлен метод. - Второй: пара ключ-значение (здесь имеется в виду объект), мы напрямую получаем пару ключ-значение через цикл, а затем передаем
append
добавлен метод.
Пример
Пример кода адреса:GitHub.com/годо точка точка…
Откройте браузер и введите:http://127.0.0.1:4000/headers
Итак, как мы его используем? Сначала нам нужно пройтиnew Headers()
для создания экземпляра объекта Headers, который возвращает пустой список. После того, как у нас есть экземпляр объекта, мы можем делать с интерфейсом то, что хотим.Давайте рассмотрим следующий пример:
function printHeaders(headers) {
let str = '';
for (let header of headers.entries()) {
str += `
<li>${header[0]}: ${header[1]}</li>
`;
console.log(header[0] + ': ' + header[1]);
}
return `<ul>
${str}
</ul>`;
}
const headers = new Headers();
// 我们打印下看看是否返回的是一个空的列表
const before = printHeaders(headers); // 发现这里没有任何输出
document.getElementById('headers-before').innerHTML = before;
// 我们添加一个请求头
headers.append('Content-Type', 'text/plain');
headers.append('Content-Type', 'text/html');
headers.set('Content-Type', ['a', 'b']);
const headers2 = new Headers({
'Content-Type': 'text/plain',
'X-Token': 'abcdefg',
});
const after = printHeaders(headers); // 输出:content-type:
Если вы чувствуете, что каждый разappend
В случае проблем вы также можете передать указанный заголовок в конструкторе, например:
const headers2 = new Headers({
'Content-Type': 'text/plain',
'X-Token': 'abcdefg'
});
printHeaders(headers2);
// 输出:
// content-type: text/plain
// x-token: abcdefg
Здесь я добавляю пользовательский заголовокX-Token
, что очень распространено и практично в практической разработке. Но помниCORSДолжны быть соблюдены соответствующие спецификации, иначе возникнет междоменная ошибка.
ты можешь пройтиappend
,delete
,set
,get
а такжеhas
метод для изменения заголовков запроса. Прямо здесьset
а такжеappend
Специальное описание метода:
set
: если вы работаете с существующим заголовком, новое значение заменит старое значение, а старое значение не будет существовать. Если заголовок не существует, добавьте новый заголовок напрямую.
append
: если заголовок уже существует, новое значение добавляется непосредственно к концу, а старое значение также сохраняется.
Для легкой памяти нужно просто запомнитьset
покроет, покаappend
будет добавлено.
Guard
Охранник - это особенность заголовков, он опекун. Это влияет на некоторые методы (какappend
,set
,delete
) можно изменить заголовок заголовка.
Он может иметь следующие значения:immutable
,request
,request-no-cors
,response
илиnone
.
Вам не нужно беспокоиться об этом здесь, просто чтобы вы знали, что есть такая вещь, влияющая на нас, чтобы установить некоторые заголовки. Вы также не можете манипулировать им, это прокси-вещь. В качестве простого примера, мы не можем вставить заголовки ответаSet-Cookie
.
Если вы хотите узнать более подробную информацию, пожалуйста, обратитесь к конкретной спецификацииconcept-headers-guardа такжеMDN Guard
Уведомление
- Когда мы присваиваем значение голове, нам нужно удовлетворитьНабор приемлемых полей заголовкаВ противном случае будет сообщено
TypeError
.
Body
Тело, если быть точным, здесь простоmixin, представляющий тело запроса или тело ответа, указанноеResponse
а такжеRequest
реализовать.
Давайте посмотрим, какие у него есть интерфейсы:
interface mixin Body {
readonly attribute ReadableStream? body;
readonly attribute boolean bodyUsed;
[NewObject] Promise<ArrayBuffer> arrayBuffer();
[NewObject] Promise<Blob> blob();
[NewObject] Promise<FormData> formData();
[NewObject] Promise<any> json();
[NewObject] Promise<USVString> text();
};
// 来自 https://fetch.spec.whatwg.org/#body
Интерфейс, определенный в спецификации, может соответствоватьMDNдля просмотра вы можете нажатьздесьБолее интуитивно понятно, какие свойства и методы мы можем использовать.
Здесь следует отметить, что эти методы возвращаютPromise
, помните, что это основано наfetch
Это очень важно при выполнении интерфейсных запросов. Помните об этом, это поможет нам понять в следующих статьяхfetch
Применение.
Пример
Примеры будут вResponse
отражено в.
Request
Запрос представляет класс запроса, который необходимо создать для создания объекта запроса. Через этот объект можно описатьHTTPЗапрос в запросе (обычно содержит заголовки запроса и тело запроса). Поскольку он используется для описания объекта запроса, объект запроса должен иметь способ изменить заголовок запроса (Заголовки) и тело запроса (Тело). Давайте сначала посмотрим, какие интерфейсы есть у Request в спецификации:
typedef (Request or USVString) RequestInfo;
[Constructor(RequestInfo input, optional RequestInit init),
Exposed=(Window,Worker)]
interface Request {
readonly attribute ByteString method;
readonly attribute USVString url;
[SameObject] readonly attribute Headers headers;
readonly attribute RequestDestination destination;
readonly attribute USVString referrer;
readonly attribute ReferrerPolicy referrerPolicy;
readonly attribute RequestMode mode;
readonly attribute RequestCredentials credentials;
readonly attribute RequestCache cache;
readonly attribute RequestRedirect redirect;
readonly attribute DOMString integrity;
readonly attribute boolean keepalive;
readonly attribute boolean isReloadNavigation;
readonly attribute boolean isHistoryNavigation;
readonly attribute AbortSignal signal;
[NewObject] Request clone();
};
Request includes Body;
dictionary RequestInit {
ByteString method;
HeadersInit headers;
BodyInit? body;
USVString referrer;
ReferrerPolicy referrerPolicy;
RequestMode mode;
RequestCredentials credentials;
RequestCache cache;
RequestRedirect redirect;
DOMString integrity;
boolean keepalive;
AbortSignal? signal;
any window; // can only be set to null
};
enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "image", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style", "track", "video", "worker", "xslt" };
enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
enum RequestCredentials { "omit", "same-origin", "include" };
enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };
enum RequestRedirect { "follow", "error", "manual" };
// 来自 https://fetch.spec.whatwg.org/#request-class
Интерфейс, определенный в спецификации, может соответствоватьMDNдля просмотра вы можете нажатьздесьДавайте более интуитивно посмотрим, какие свойства и методы он может нам использовать, и мы не будем объяснять их здесь по одному.
Обратите внимание, что все свойства здесь доступны только для чтения, в спецификации мы видим, что первый параметр конструктораRequest
Объект или строка, мы вообще берем строку, то есть адрес ресурса, к которому нужно получить доступ (HTTPадрес интерфейса). Второй параметр получаетRequestInit
Необязательный объект, и этот объект является словарем. существуетjavascript
, мы можем понимать это как объект ({}).RequestInit
Внутри мы можем настроить начальные свойства, сообщаяRequest
Некоторая информация о конфигурации для нашего запроса.
Здесь необходимо обратить особое внимание на следующие свойства.
modeЯвляетсяRequestMode
Тип перечисления, возможные значенияnavigate
, same-origin
, no-cors
, cors
. Указывает, используется ли запросCORSили используйте режим строгой гомологии. В междоменной ситуации вы должны установитьcors
. Значение по умолчанию для этого значения используетRequest
При инициализации по умолчаниюcors
. Когда встроенные ресурсы запускаются с тегами, такими как<link>
,<script>
Ярлыки (не измененные вручнуюcrossoriginсвойство), по умолчаниюno-cors
. Для получения подробной информации см.whatwgнорма илиMDN.
credentialsЯвляетсяRequestCredentials
Тип перечисления, возможные значенияomit
, same-origin
, include
. Указывает, отправляется ли запрос в междоменной ситуации.cookie
. посмотри это если правильноXHRСтуденты, которые знают его, должны быть знакомы с ним. с участиемXHRсерединаwithCredentials
очень похожий. ноcredentials
Есть три необязательных значения, его значение по умолчанию равноsame-origin
. Когда вам нужно пройти через доменыcookie
учетные данные, установите его наinclude
. Обратите внимание, что здесь есть детали, когда установлено значениеinclude
, Пожалуйста, убедитесьResponse Header
серединаAccess-Control-Allow-Origin
не может быть*
, необходимо указать источник (например:http://127.0.0.1:4001), иначе вы увидите следующее сообщение об ошибке в консоли. Для получения подробной информации см.whatwgнорма илиMDN.
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
Вы можете использовать код, приведенный в статье, чтобы начать cors образец кодаЗатем введите браузер http://127.0.0.1:4001/request, если ничего другого, вы можете увидеть вышеуказанное сообщение об ошибке в консоли.
bodyЯвляетсяBodyInitТипы. Его возможные значенияBlob
,BufferSource
, FormData
, URLSearchParams
, ReadableStream
, USVString
. Внимательные ученики не знают, нашли ли они его, мы частоjson
Объекта нет. Поэтому, если нам нужно пройтиjson
Если вам нужно позвонитьJSON.stringify
функция, которая поможет нам преобразовать в строку.
Пример кода приведен ниже.
Пример
Пример кода адреса:GitHub.com/годо точка точка…
Откройте браузер и введите:http://127.0.0.1:4000/request
// 客户端
const headers = new Headers({
'X-Token': 'fe9',
});
const request = new Request('/api/request', {
method: 'GET',
headers,
});
console.log(request); // Request {method: "GET", url: "http://127.0.0.1:4000/api/request", headers: Headers, destination: "", referrer: "about:client", …}
console.log(request.method); // GET
console.log(request.mode); // cors
console.log(request.credentials); // same-origin
// 如果你想打印headers信息,可以调用 printHeaders(request.headers)
Здесь мы первыеGET
Простой запрос в качестве примера, мы передаем пользовательскийHeaders
, указав метод запросаmethod
дляGET
(по умолчаниюGET
). В приведенной выше спецификации интерфейса мы можем передатьRequest
Объект получает некоторые часто используемые свойства, такие какmethod
,url
,headers
,body
и так далее свойства только для чтения.
Response
Response аналогичен Request и представляет данные ответа, возвращаемые запросом. Давайте сначала посмотрим, какие интерфейсы определены в спецификации.
[Constructor(optional BodyInit? body = null, optional ResponseInit init), Exposed=(Window,Worker)]
interface Response {
[NewObject] static Response error();
[NewObject] static Response redirect(USVString url, optional unsigned short status = 302);
readonly attribute ResponseType type;
readonly attribute USVString url;
readonly attribute boolean redirected;
readonly attribute unsigned short status;
readonly attribute boolean ok;
readonly attribute ByteString statusText;
[SameObject] readonly attribute Headers headers;
readonly attribute Promise<Headers> trailer;
[NewObject] Response clone();
};
Response includes Body;
dictionary ResponseInit {
unsigned short status = 200;
ByteString statusText = "";
HeadersInit headers;
};
enum ResponseType { "basic", "cors", "default", "error", "opaque", "opaqueredirect" };
// 来自 https://fetch.spec.whatwg.org/#response-class
Интерфейс, определенный в спецификации, может соответствоватьMDNдля просмотра вы можете нажатьздесьДавайте более интуитивно посмотрим, какие свойства и методы он может нам использовать, и мы не будем объяснять их здесь по одному.
вstatus
, headers
Свойства используются чаще всего. пройти черезstatus
Код состояния мы можем судить о результате обработки запроса сервера, например200
, 403
и т.д. Общие коды состояния. Вот пример, когдаstatus
для401
, вы можете перехватить и перейти на страницу входа в систему во внешнем интерфейсе, которая сейчасSPA
(Одностраничные приложения). мы также можем использоватьheaders
Чтобы получить некоторую информацию, возвращаемую сервером во внешний интерфейс, напримерtoken
.
Студенты, которые внимательно изучают приведенный выше интерфейс, могут обнаружить, чтоResponse includes Body;
такая идентификация. Раньше мы говорилиBody
Зависит отRequest
а такжеResponse
выполнить. такBody
есть метод вResponse
Можно использовать экземпляры, и это тоже очень важная часть, проходимBody
Предоставленный метод (здесь точно определяетсяResponse
Реализовано) для обработки данных, возвращаемых сервером.
Ниже мы будем использовать пример, чтобы понять простое использование:
Пример
Расположение примера кода:GitHub.com/годо точка точка…
// 客户端
const headers = new Headers({
'X-Token': 'fe9-token-from-frontend',
});
const request = new Request('/api/response', {
method: 'GET',
headers,
});
// 这里我们先发起一个请求试一试
fetch(request)
.then(response => {
const { status, headers } = response;
document.getElementById('status').innerHTML = `${status}`;
document.getElementById('headers').innerHTML = headersToString(headers);
return response.json();
})
.then(resData => {
const { status, data } = resData;
if (!status) {
window.alert('发生了一个错误!');
return;
}
document.getElementById('fetch').innerHTML = data;
});
Здесь мы игнорируемfetch
использования, которые будут подробно описаны в следующих главах. Сосредоточимся на первомthen
Метод вызывает то, что внутри. Видно, что возвратresponse
объект, этот объект нашResponse
пример. взято в примерstatus
а такжеheaders
, для удобства здесь выложил в html. Глядя на последнюю строку обратного вызова, мы вызываемresponse.json()
метод (данные, возвращаемые здесь, являютсяJSON
объекта, для удобства прямого вызоваjson()
), метод возвращаетPromise
, возвращаем результат обработки последнемуthen
Обратный вызов, чтобы можно было получить окончательные обработанные данные.
Откройте браузер и введитеhttp://127.0.0.1:4000/response, если код вашего примера работает правильно, вы увидите следующую страницу:
(см. данные, возвращаемые Response)
Примечание редактора: эта статья незакончена.
Искусство /GoDotDotDot
Less is More.
редактировать /флуоресценция
Другие статьи автора:
Отличные темы, которые необходимо знать: мы должны сделать все возможное для оптимизации
Эта статья авторизована и опубликована автором Chuangyu Front-end, а авторские права принадлежат автору, созданному Chuangyu Front-end. Пожалуйста, укажите источник для перепечатки этой статьи. Ссылка на статью:blog.Godot точка точка.com/2018/12/28/…
Если вы хотите подписаться на другие сообщения с передовой линии KnownsecFED, выполните поиск и подпишитесь на нашу общедоступную учетную запись WeChat: KnownsecFED. Добро пожаловать, чтобы оставить сообщение для обсуждения, мы ответим как можно скорее.
Спасибо за прочтение.
С новым годом :)