1. Введение
- Хотя многие люди начинают работу с ES6, они обращаются к учебнику по ES6 Учителя Руана Ифэна.Начало работы с ECMAScript 6, но обратите внимание, г-н Руан в начале предложил, что если ваша база js недостаточно прочна, вам следует сначала заложить прочную основу, а затем вернуться к изучению es6. Выходи и миксуй, долг ES5 рано или поздно будет погашен! ! (ссылаясь на базовые знания до ES6)
Точка знаний 1: Объекты описания атрибутов (Ссылка на подробности)
Примечание. Если приведенный ниже основной вопрос не является для вас подходящим ответом, щелкните ссылку с подробной информацией выше, чтобы систематически изучать эту точку знаний.
JavaScript предоставляет внутреннюю структуру данных для описания свойств объекта и управления его поведением, например, является ли свойство доступным для записи, обхода и т. д. Эта внутренняя структура данных называется属性描述对象
(атрибуты объекта)
1 Вопрос 1: Что такое объекты описания атрибута?
- value
- writable
- enumerabele
- configurable
- get
- set
2 Вопрос 2. Роль параметра configurable и влияние установки для него значения false
configurable(可配置性)
Возвращает логическое значение, определяющее, можно ли изменить объект описания свойства. То есть, когда configurable имеет значение false, value, writable, enumerable и configurable не могут быть изменены.
var obj = Object.defineProperty({}, 'p', {
value: 1,
writable: false,
enumerable: false,
configurable: false
});
Object.defineProperty(obj, 'p', {value: 2})
// TypeError: Cannot redefine property: p
Object.defineProperty(obj, 'p', {writable: true})
// TypeError: Cannot redefine property: p
Object.defineProperty(obj, 'p', {enumerable: true})
// TypeError: Cannot redefine property: p
Object.defineProperty(obj, 'p', {configurable: true})
// TypeError: Cannot redefine property: p
В приведенном выше коде параметр obj.p имеет значение false. Затем измените значение, доступное для записи, перечисляемое и настраиваемое, и результатом будет ошибка.
Обратите внимание, что записываемый сообщит об ошибке только в том случае, если значение false изменено на true, а значение true на false разрешено.
var obj = Object.defineProperty({}, 'p', {
writable: true,
configurable: false
});
Object.defineProperty(obj, 'p', {writable: false})
// 修改成功
至于value,只要writable和configurable有一个为true,就允许改动。
var o1 = Object.defineProperty({}, 'p', {
value: 1,
writable: true,
configurable: false
});
Object.defineProperty(o1, 'p', {value: 2})
// 修改成功
var o2 = Object.defineProperty({}, 'p', {
value: 1,
writable: false,
configurable: true
});
Object.defineProperty(o2, 'p', {value: 2})
// 修改成功
Кроме того, когда для записи установлено значение false, назначается прямой целевой атрибут, об ошибке не сообщается, но он не будет успешным.
var obj = Object.defineProperty({}, 'p', {
value: 1,
writable: false,
configurable: false
});
obj.p = 2;
obj.p // 1
В приведенном выше коде для записи obj.p установлено значение false, и прямое присвоение obj.p не будет иметь эффекта. Если это строгий режим, он также сообщит об ошибке.
Возможность настройки определяет, можно ли удалить целевое свойство.
var obj = Object.defineProperties({}, {
p1: { value: 1, configurable: true },
p2: { value: 2, configurable: false }
});
delete obj.p1 // true
delete obj.p2 // false
obj.p1 // undefined
obj.p2 // 2
В приведенном выше коде настраиваемый параметр obj.p1 равен true, поэтому его можно удалить, но obj.p2 удалить нельзя.
Дальше я не буду писать вопросы.Если вы плохо ответите на вышеприведенные вопросы, вы можете перейти по ссылке, чтобы начать школу, хе-хе
База знаний 2: объект RegExp (Ссылка на подробности)
Примечание. Если приведенный ниже основной вопрос не является для вас подходящим ответом, щелкните ссылку с подробной информацией выше, чтобы систематически изучать эту точку знаний.
1 Вопрос 1: Знаете ли вы, что означают \1 и \2 в регулярных выражениях?
/(.)b(.)\1b\2/.test("abcabc") // true
- Внутри регулярного выражения вы также можете использовать \n для ссылки на содержимое, соответствующее скобкам, где n — натуральное число, начинающееся с 1, указывающее соответствующий порядок скобок.
- В приведенном выше коде
\1
означает, что первая скобка соответствует (т.е. a),\2
Указывает, чему соответствует вторая скобка (т.е. c).
2 В String.prototype.replace() второй параметр может быть строкой или функцией.Если это строка, что означают $1 и $2?
'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1')
// "world hello"
Второй параметр метода replace может использовать знак доллара.$
, используется для обозначения замененного содержимого.
- $&: совпавшая подстрока.
- $`: соответствует тексту, предшествующему результату.
- $': Соответствует тексту, следующему за результатом.
- $n: n-я группа контента, которая соответствует успешному совпадению, n — натуральное число, начинающееся с 1.
- ?: Относится к знаку доллара $.
3 Что такое жадный режим?
var s = 'aaa';
s.match(/a+/) // ["aaa"]
s.match(/a+?/) // ["a"]
Почему вышеуказанное отличается, потому что дважды+
после этого есть?
, который является флагом включения нежадного режима.
В дополнение к знаку плюс для нежадного режима, есть также звездочка (*) для нежадного режима и вопросительный знак (?) для нежадного режима.
- +?: Указывает, что определенный шаблон появляется один или несколько раз, и при сопоставлении используется нежадный шаблон.
- *?: Указывает, что шаблон появляется 0 или более раз и при сопоставлении используется нежадный шаблон.
- ??: определенный шаблон в таблице встречается 0 или 1 раз, и при сопоставлении используется нежадный шаблон.
4 Пожалуйста, посмотрите следующий случай, зачем возвращать false?Знаете ли вы свойство lastIndex?
var r = /x/g;
var s = '_x_x';
r.lastIndex = 4;
r.test(s) // false
5 Для метода сопоставления строк первым параметром может быть регулярка.Есть ли проблема с шаблоном с g в регулярке?
Обратите внимание, что при использовании группового сопоставления его не следует использовать одновременно.g
модификатор, иначе метод match не захватит содержимое группы.
var m = 'abcabc'.match(/(.)b(.)/g);
m // ['abc', 'abc']
Как видите, группа захвата не захватывает содержимое группы. но совпадение не добавляетg
В режиме вы можете захватывать содержимое группы захвата, с которой вы столкнулись впервые.
var m = 'abcabc'.match(/(.)b(.)/);
m
// ['abc', 'a', 'c']
6 Знаете ли вы о незахватывающих группах, утверждениях с опережением, отрицательных утверждениях с опережением?
(?:x)
Это называется группой без захвата, что означает, что совпадающее содержимое группы не возвращается, то есть круглые скобки не включаются в результат сопоставления.
var m = 'abc'.match(/(?:.)b(.)/);
m // ["abc", "c"]
Шаблон в приведенном выше коде использует всего две круглые скобки. Первая скобка — это группа без захвата, поэтому в окончательном возвращаемом результате нет первой скобки, а есть только содержимое, соответствующее второй скобке.
x(?=y)
Это называется позитивным взглядом вперед,x
только вy
совпадение раньше,y
не будут учитываться в возвращаемых результатах. Например, чтобы сопоставить число, за которым следует знак процента, напишите/\d+(?=%)/
.
В «прогнозируемом утверждении» часть в круглых скобках не будет возвращена.
var m = 'abc'.match(/b(?=c)/);
m // ["b"]
В приведенном выше коде используется утверждение с опережением, b находится перед c, поэтому оно соответствует, но c, соответствующее скобкам, не будет возвращено.
x(?!y)
называется негативным просмотром вперед,x
только отсутствуетy
Предыдущее совпадение y не будет включено в возвращаемый результат. Например, чтобы сопоставить числа, за которыми не следует знак процента, напишите/\d+(?!%)/
/\d+(?!\.)/.exec('3.14')
// ["14"]
В приведенном выше коде регулярное выражение указывает, что будут сопоставляться только числа, не предшествующие десятичной запятой, поэтому возвращаемый результат равен 14.
В «упреждающем отрицательном утверждении» часть в скобках не возвращается.
var m = 'abd'.match(/b(?!c)/);
m // ['b']
В приведенном выше коде используется отрицательное утверждение с опережением, b не находится перед c, поэтому оно соответствует, а d, соответствующий скобкам, не будет возвращен.
База знаний 3: Объекты-экземпляры и новая команда (Ссылка на подробности)
1 Знаете ли вы принцип новой команды?
При использовании новой команды функция, следующая за ней, последовательно выполняет следующие шаги.
- Создает пустой объект в качестве возвращаемого экземпляра объекта.
- Укажите прототип этого пустого объекта на свойство прототипа конструктора.
- Назначьте этот пустой объект ключевому слову this внутри функции.
- Начните выполнять код внутри конструктора.
2 Знаете new.target, Object.create()?
можно использовать внутри функцииnew.target
Атрибуты. Если текущая функция вызывается новой командой, new.target указывает на текущую функцию, в противном случае она не определена.
function f() {
console.log(new.target === f);
}
f() // false
new f() // true
Конструкторы действуют как шаблоны и могут генерировать экземпляры объектов. Однако иногда вы не можете получить конструктор, только существующий объект. Мы хотим использовать этот существующий объект в качестве шаблона для создания нового экземпляра объекта, тогда мы можем использоватьObject.create()
метод.
var person1 = {
name: '张三',
age: 38,
greeting: function() {
console.log('Hi! I\'m ' + this.name + '.');
}
};
var person2 = Object.create(person1);
person2.name // 张三
person2.greeting() // Hi! I'm 张三.
В приведенном выше коде объект person1 является шаблоном объекта person2, который наследует свойства и методы первого.
База знаний 4: Модель событий DOM
1 Куда указывает this функции слушателя в DOM? (Ссылка на подробности)
// 例如:
// HTML 代码如下
// <button id="btn">点击</button>
var btn = document.getElementById('btn');
btn.addEventListener(
'click',
function (e) {
console.log(this.id);
},
false
);
В приведенном выше кодеthis
Указывает на узел элемента, вызвавший событие
2 Проблемы, связанные с событиями мыши? (Ссылка на подробности)
2.1 Что такое событие двойного щелчка мыши и какое событие запускается при нажатии правой кнопки мыши?
-
dblclick
: Запускается, когда мышь дважды щелкает один и тот же элемент. -
contextmenu
: срабатывает при нажатии правой кнопки мыши (до появления контекстного меню) или при нажатии «клавиши контекстного меню».
2.2 В чем разница между clientX, screenX и offsetX в событиях мыши?
-
MouseEvent.clientX
Свойство возвращает горизонтальную координату (в пикселях) положения мыши относительно левого верхнего угла окна браузера. -
MouseEvent.screenX
Свойство возвращает горизонтальную координату (в пикселях) положения мыши относительно левого верхнего угла экрана. -
MouseEvent.offsetX
Свойство возвращает горизонтальное расстояние (в пикселях) между положением мыши и краем отступа с левой стороны целевого узла.
Схема выглядит следующим образом:
2.3 Как узнать, нажал ли пользователь клавишу Caps?
MouseEvent.getModifierState
Метод возвращает логическое значение, указывающее, была ли нажата определенная функциональная клавиша. Его аргументом является строка, представляющая функциональную клавишу.
document.addEventListener('click', function (e) {
console.log(e.getModifierState('CapsLock'));
}, false);
База знаний 5: Проблемы, связанные с сенсорными событиями? (Ссылка на подробности)
1 Что такое сенсорный список?
- Массив объектов Touch, полученный с помощью event.touches.
- Объект Touch представляет собой точку касания. Когда к экрану прикасаются несколько пальцев, TouchList будет хранить несколько объектов Touch.
2 В чем разница между TouchEvent.touches и TouchEvent.changedTouches в событиях касания?
- changeTouches также является
TouchList
объект, дляtouchstart
событие, этоTouchList
Объект перечисляет недавно добавленные точки взаимодействия в этом событии. - для
touchmove
События, список точек соприкосновения, которые изменились по сравнению с последним событием. дляtouchend
, в котором перечислены контакты, покидающие сенсорную плоскость (они соответствуют пальцам, которые больше не соприкасаются с сенсорной плоскостью).
Особое внимание следует уделить touchend здесь, touches и targetTouches хранят только те контакты, которые касаются экрана, а changeTouches следует использовать для получения последнего состояния контакта.
Пункт знаний 6 Проблемы, связанные с событием перетаскивания? (Ссылка на подробности)
1 Какие события связаны с целью перетаскивания и события связаны с целью перетаскивания?
Привязать к цели перетаскивания
название события | описывать |
---|---|
dragstart | Запускается, когда пользователь начинает перетаскивать элемент или блок выбора текста. |
drag | Запускается, когда пользователь перетаскивает элемент или блок выбора текста |
dragend | Запускается, когда пользователь заканчивает перетаскивание элемента или блока выбора текста. (например, отпустив кнопку мыши или нажав клавишу ESC на клавиатуре) |
Привязка к целевому объекту
название события | описывать |
---|---|
dragenter | Запускается, когда пользователь начинает перетаскивать элемент или блок выбора текста. |
dragover | Запускается, когда пользователь перетаскивает элемент или блок выбора текста |
dragleave | Запускается, когда пользователь заканчивает перетаскивание элемента или блока выбора текста. (например, отпустив кнопку мыши или нажав клавишу ESC на клавиатуре) |
drop | Запускается, когда элемент или текстовый блок выбора перетаскивается на допустимую цель перетаскивания. |
2 Загрузка файла из операционной системы в браузер вызовет события dragstart и dragend?
Не будет
3 Почему событие по умолчанию (event.preventDefault()) предотвращается при перетаскивании?
- Поскольку большинство областей веб-страницы не подходят в качестве целевого узла для перетаскивания элементов, настройка этого события по умолчанию такова, что текущий узел не позволяет принимать перетаскиваемые элементы.
- Если вы хотите удалить данные на целевом узле, вы должны сначала предотвратить поведение этих двух событий по умолчанию.
4 При перетаскивании каждый объект события имеет объект DataTransfer для сохранения перетаскиваемых данных.Извините, в чем разница между свойством dropEffect и свойством effectAllowed в DataTranfer?
-
DataTransfer.dropEffect
Атрибуты используются для установки дропа(drop)
Эффект при перетаскивании узла влияет на форму мыши при перетаскивании соответствующей области. Например:
target.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
e.dataTransfer.dropEffect = 'copy';
});
-
DataTransfer.effectAllowed
Свойство устанавливает эффекты, разрешенные в этом перетаскивании. Например:
source.addEventListener('dragstart', function (e) {
e.dataTransfer.effectAllowed = 'move';
});
target.addEventListener('dragover', function (e) {
ev.dataTransfer.dropEffect = 'move';
});
5 Как использовать объект dataTransfer для передачи данных?
в основном используетсяDataTransfer.setData()
а такжеDataTransfer.getData()
метод, такой как
document.addEventListener('dragstart', function (event) {
// 被拖拉节点的背景色变透明
event.dataTransfer.setData('data',this.nodeName);
}, false);
document.addEventListener('drop', function( event ) {
// 防止事件默认行为(比如某些元素节点上可以打开链接),
event.preventDefault();
console.log(event.dataTransfer.getData('data'))
}, false);
База знаний 6 Сценарии загрузки браузера и проблемы, связанные с рендерингом (Ссылка на подробности)
1 Расскажите, пожалуйста, вкратце о принципе загрузки js-скрипта в браузере?
Обычный процесс загрузки страницы выглядит так.
- Браузер начинает синтаксический анализ HTML-страницы по мере ее загрузки. То есть он не ждет, пока загрузка завершится, а затем начинает синтаксический анализ.
- В процессе синтаксического анализа, когда браузер находит элемент
- Если элемент
- После выполнения механизма JavaScript управление возвращается механизму рендеринга, и веб-страница HTML возобновляется для синтаксического анализа.
2 Почему браузер приостанавливает отрисовку страницы при загрузке внешних скриптов?
Причина в том, что код JavaScript может изменять DOM, поэтому управление должно быть передано ему, иначе это приведет к сложным проблемам гонки потоков.
3 Исходя из приведенного выше принципа загрузки js-скрипта, почему js-скрипт лучше всего размещать внизу страницы?
-
Если внешний скрипт загружается долго (загрузка не может быть завершена все время), тогда браузер будет ждать завершения загрузки скрипта, в результате чего веб-страница перестанет отвечать на запросы в течение длительного времени, и браузер появится в состояние «подвешенной смерти», которое называется «блокирующим эффектом».
-
Во избежание такой ситуации все теги
4 Будет ли загрузка css блокировать синтаксический анализ DOM? Будет ли загрузка css блокировать рендеринг DOM?
Загрузка и синтаксический анализ CSS не блокирует синтаксический анализ HTML, но блокирует рендеринг.
5 Какие известные движки рендеринга для разных браузеров? Каков процесс рендеринга движка рендеринга?
Разные браузеры имеют разные механизмы рендеринга.
- Firefox: движок Gecko
- Safari: движок WebKit
- Chrome: движок Blink
- IE: двигатель «Трайдент»
- Edge: движок EdgeHTML
Механизм рендеринга обрабатывает веб-страницы, как правило, в четыре этапа.
- Анализ кода: код HTML анализируется в DOM, а код CSS анализируется в CSSOM (объектная модель CSS).
- Композиция объекта: объедините DOM и CSSOM в дерево рендеринга.
- Макет: вычисляет макет дерева рендеринга.
- Draw: рисует визуализированное дерево на экране.
Вышеуказанные четыре этапа не выполняются строго в порядке. Часто второе и третьи шаги уже начались до того, как первый шаг завершен. Итак, вы увидите: HTML-код веб-страницы не был загружен, но браузер уже отображает содержимое.
5.5 Какие перемотки назад и перекомпоновки происходят при рендеринге в браузере?
-
Дерево рендеринга преобразуется в макет веб-страницы, который называется
布局流(flow)
; Процесс отображения макета на странице называется绘制(paint)
. Все они имеют блокирующие эффекты и потребляют много времени и вычислительных ресурсов. -
После создания страницы будут запущены операции скрипта и таблицы стилей.
重流(reflow)
а также重绘(repaint)
. Действия пользователя также могут запускать перекомпоновку и перерисовку, например, установка эффекта наведения мыши (a:hover), прокрутка страницы, ввод текста в поле ввода, изменение размера окна и т. д. -
重流
а также重绘
не обязательно происходит вместе,重流
неизбежно привести к重绘
,重绘
не обязательно требуется重流
. Например, изменение цвета элемента вызовет только перерисовку, но не перекомпоновку; изменение макета элемента вызовет перерисовку и перекомпоновку.
5.6 Примерный процесс парсинга js в браузере?
В первые дни JavaScript обрабатывался внутри браузера следующим образом:
- Прочитайте код, выполните лексический анализ и разложите код на токены.
- Разбор токенов и организация кода в «синтаксическое дерево».
- Используйте «переводчик», чтобы преобразовать код в байт-код.
- Используйте «интерпретатор байт-кода» для преобразования байт-кода в машинный код.
Преобразование байт-кода в машинный код путем построчной интерпретации неэффективно. Чтобы повысить скорость работы, современные браузеры перешли на «компилятор Just In Time» (сокращенно JIT), то есть байт-код компилируется только во время выполнения, какая бы строка ни использовалась, а результат компиляции кэшируется (inline cache ). Обычно программа используется часто, только небольшая часть кода, с кешированием результатов компиляции скорость работы всей программы будет значительно повышена.
Файлы cookie точки знаний 7 (Ссылка на подробности)
1 Каковы ограничения по количеству и размеру файлов cookie?
Различные браузеры имеют разные ограничения на количество и размер файлов cookie. Вообще говоря, количество файлов cookie, установленных для одного доменного имени, не должно превышать 30, а размер каждого файла cookie не должен превышать 4 КБ. После превышения лимита cookie будет проигнорирован и не будет установлен .
2 При каких обстоятельствах два URL-адреса могут совместно использовать файлы cookie?
Политика браузера в отношении одного и того же происхождения гласит, что два URL-адреса могут совместно использовать файлы cookie, если они имеют одно и то же доменное имя и один и тот же порт (см. главу «Политика одного и того же происхождения»). Обратите внимание, что протоколы здесь не обязательно должны быть одинаковыми. То есть,example.comУстановленный файл cookie, который может быть прочитан https://example.com.
3 В чем разница между полями Expires и Max-Age в файле cookie настройки?
-
Expires
Атрибут указывает конкретное время истечения срока действия. По истечении указанного времени браузер больше не будет сохранять файл cookie. Его значение находится в формате UTC и может использоваться сDate.prototype.toUTCString()
Преобразование форматов.
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
-
Max-Age
Атрибут: укажите количество секунд, в течение которых файл cookie будет существовать с этого момента, например 60 * 60 * 24 * 365 (то есть один год). По истечении этого времени браузер больше не будет хранить этот файл cookie. -
Если также указано
Expires
а такжеMax-Age
,ТакMax-Age
Значение будет иметь приоритет. -
если
Set-Cookie
поле не указаноExpires
илиMax-Age
атрибут, то этот файл cookie является файлом cookie сеанса, то есть он существует только в этом сеансе. Как только пользователь закроет браузер, браузер больше не будет сохранять этот файл cookie.
4 В чем разница между полями Secure и HttpOnly в файле cookie настройки?
Secure
Атрибут указывает, что браузер может отправлять этот файл cookie на сервер только по зашифрованному протоколу HTTPS. Это свойство является просто переключателем, значение указывать не нужно. Этот переключатель автоматически включается, если связь осуществляется по протоколу HTTPS.
HttpOnly
Свойство Cookie указывает, что сценарий JavaScript не может пройти, в основномdocument.cookie
Атрибуты,XMLHttpRequest
объект иRequest API
не могу получить этот атрибут.
Точка знаний 8 Проблемы, связанные с гомологичными ограничениями
1 Что означает гомология?
- тот же протокол
- такое же доменное имя
- тот же порт
23 Какие действия запрещены политикой одного и того же источника?
В настоящее время в общей сложности три поведения ограничены, если он не гомологичен.
(1) 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。
(2) 无法接触非同源网页的 DOM。
(3) 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)
3 Как HTML5 реализует передачу данных между окнами, кратко расскажите? (Подробности)
postMessage
Это API, представленный html5,postMessage()
Этот метод позволяет сценариям из разных источников эффективно взаимодействовать асинхронно, что может реализовать кросс-текстовый документ, многооконный и междоменный обмен сообщениями.Он в основном используется для обмена данными между окнами, что также делает его эффективным решение для междоменной связи план.
Приведите пример междоменной связи postMessage и представьте его API.
Родительская форма создает междоменный iframe и отправляет информацию
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<iframe src="http://127.0.0.1:9090/b.html" name="postIframe" onload="messageLoad()"></iframe>
<script>
function messageLoad(){
var url = "http://127.0.0.1:9090";
window.postIframe.postMessage("给我tsort的信息",url); //发送数据
}
window.onmessage = function(e){
e = e || event;
console.log(e.data); //接收b返回的数据,在控制台有两次输出
}
</script>
</body>
</html>
Подформа получает информацию и обрабатывает ее.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
window.onmessage = function(e){
e = e || event;
alert(e.data); //立即弹出a发送过来的数据
e.source.postMessage("好的,请稍等三秒!",e.origin); //立即回复a
var postData = {name:"tsrot",age:24};
var strData = JSON.stringify(postData); //json对象转化为字符串
setTimeout(function(){
e.source.postMessage(strData,e.origin);
},3000); //3秒后向a发送数据
}
</script>
</body>
</html>
4 Пожалуйста, представьте CORS, который преодолевает ограничение, заключающееся в том, что AJAX можно использовать только с одним и тем же источником? (Подробности)
4.1 В чем разница между простым запросом и непростым запросом в CORS?
Пока следующие два условия выполняются одновременно, это простой запрос.
1) Метод запроса является одним из следующих трех методов.
HEAD
GET
POST
2) Информация заголовка HTTP не превышает следующих полей.
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
4.2 Когда браузер обнаруживает, что этот междоменный запрос AJAX является простым запросом, он автоматически добавляет, какое поле к информации заголовка, и что это означает?
Добавьте поле происхождения. Укажите, с какого домена пришел этот запрос (протокол + имя домена + порт)
4.3 Что происходит с браузером, если адрес, указанный origin, не входит в область разрешения сервера, какие поля будут добавлены в заголовок ответа в рамках разрешения сервера?
еслиOrigin
Указанный источник не входит в область разрешений, сервер вернет обычный HTTP-ответ. Браузер обнаружил, что информация заголовка этого ответа не содержитAccess-Control-Allow-Origin
поле (подробнее см. ниже), вы знаете, что что-то пошло не так, и выдается ошибка, называемаяXMLHttpRequest
изonerror
Захват функции обратного вызова. Обратите внимание, что этот тип ошибки не может быть идентифицирован по коду состояния, так как код состояния ответа HTTP может быть 200.
еслиOrigin
Если указанное доменное имя находится в допустимом диапазоне, ответ, возвращаемый сервером, будет содержать несколько дополнительных полей заголовка.
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
4.4 Что означает Access-Control-Allow-Credentials: true?
-
CORS
Запрос по умолчанию не содержит информации о файлах cookie (а также информации об аутентификации HTTP и т. д.), что снижает риск CSRF-атак. - Однако в некоторых случаях серверу может потребоваться получить файл cookie, и в этом случае серверу необходимо явно указать
Access-Control-Allow-Credentials
поле, которое сообщает браузеру, что cookie может быть отправлен.
4.5 Что такое предварительный запрос в сложном запросе и чем отличаются заголовки этого запроса от обычных запросов?
- Для запросов CORS, которые не являются простыми запросами, перед формальным общением будет добавлен запрос HTTP-запроса, который называется
预检请求(preflight)
. - Браузер сначала запрашивает у сервера, находится ли доменное имя текущей страницы в списке разрешенных сервером и какие методы HTTP и поля заголовков доступны.
Пример:
var url = 'http://api.alice.com/cors';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.send();
В приведенном выше коде метод HTTP-запросаPUT
и отправить собственный заголовокX-Custom-Header
.
Браузер обнаруживает, что это непростой запрос, и автоматически выдает «предварительный» запрос, запрашивая у сервера подтверждение того, что он может это сделать. Ниже приведены заголовки HTTP для этого «предварительного» запроса.
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
Метод запроса, используемый в запросе «preflight», — OPTIONS, что означает, что этот запрос используется для запроса. В информации заголовка ключевым полем являетсяOrigin
, указывающее, откуда пришел запрос.
КромеOrigin
поле, информация заголовка «предпечатного» запроса включает два специальных поля.
(1)Access-Control-Request-Method
Это поле является обязательным и используется для перечисления методов HTTP, которые будут использоваться в CORS-запросе браузера.Приведенный выше пример — PUT.
(2)Access-Control-Request-Headers
Это поле представляет собой строку с разделителями-запятыми, которая указывает дополнительные поля заголовка, которые браузер будет отправлять в запросах CORS.Приведенный выше пример — X-Custom-Header.
4.6 Ответ на предварительный запрос?
- Для запросов CORS, которые не являются простыми запросами, перед формальным общением будет добавлен запрос HTTP-запроса, который называется
预检请求(preflight)
. - Браузер сначала запрашивает у сервера, находится ли доменное имя текущей страницы в списке разрешенных сервером и какие методы HTTP и поля заголовков доступны.
После того, как сервер получает запрос «preflight», он проверяетOrigin
,Access-Control-Request-Method
а такжеAccess-Control-Request-Headers
После подтверждения того, что запросы из разных источников разрешены, вы можете ответить.
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
Точка знаний 9 Доступ объекта истории к проблемам, связанным с API истории сеансов браузера? (Ссылка на подробности)
1 Что означает history.pushState(), будет ли он переходить на веб-страницу?
Метод History.pushState() используется для добавления записи в историю.
window.history.pushState(state, title, url)
Метод принимает три параметра по порядку:
- состояние: объект состояния, связанный с добавленной записью, в основном используемый для
popstate
мероприятие. Когда событие срабатывает, объект будет передан в функцию обратного вызова. То есть браузер сериализует объект и сохраняет его локально, а когда страница перезагружается, он может получить объект. Если вам не нужен этот объект, вы можете указать здесь null. - title: Заголовок новой страницы. Однако теперь все браузеры игнорируют этот параметр, поэтому здесь можно заполнить пустую строку.
- URL-адрес: новый URL-адрес, который должен находиться в том же домене, что и текущая страница. Адресная строка вашего браузера отобразит этот URL. Предполагая, что текущий URL-адрес — example.com/1.html, используйте метод pushState(), чтобы добавить новую запись в запись просмотра (объект History).
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
Этот API не перенаправляет веб-страницы.
2 После history.pushState() какое событие будет вызвано, когда пользователь нажмет кнопку «Назад» в браузере?
вызовет событие popstate Способ применения следующий
window.addEventListener('popstate', function(event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
});
Вопросы, связанные с URL-адресом пункта 10 знаний? (Ссылка на подробности)
1 При кодировании и декодировании URL-адреса могут содержать только два типа допустимых символов, какие два типа?
- Метасимволы URL:
分号(;)
,逗号(,)
,斜杠(/)
,问号(?)
,冒号(:)
,at(@)
,&
,等号(=)
,加号(+)
,美元符号($)
,井号(#)
- Семантические символы:
a-z
,A-Z
,0-9
,连词号(-)
,下划线(_)
,点(.)
,感叹号(!)
,波浪线(~)
,星号(*)
,单引号(')
,圆括号(())
В дополнение к вышеуказанным символам, другие символы в URL-адресе должны быть экранированы.Правило состоит в том, чтобы преобразовать каждый байт в знак процента (%) плюс две заглавные шестнадцатеричные буквы в соответствии с кодировкой операционной системы по умолчанию.
2 Какие методы кодирования/декодирования URL предоставляет URL?
JavaScript предоставляет четыре метода кодирования/декодирования URL.
- encodeURI()
- encodeURIComponent()
- decodeURI()
- decodeURIComponent()
1. кодироватьURI()
Метод encodeURI() используется для перекодирования всего URL. Его аргументом является строка, представляющая весь URL-адрес. Он экранирует все символы, кроме метасимволов и семантических символов.
encodeURI('http://www.example.com/q=春节')
// "http://www.example.com/q=%E6%98%A5%E8%8A%82"
2. кодироватьURIComponent()
Метод encodeURIComponent() используется для перекодирования компонентов URL, при этом будут перекодированы все символы, кроме семантических, то есть метасимволы также будут перекодированы. Поэтому его нельзя использовать для перекодирования всего URL-адреса. Он принимает один параметр, который является фрагментом URL-адреса.
encodeURIComponent('春节')
// "%E6%98%A5%E8%8A%82"
encodeURIComponent('http://www.example.com/q=春节')
// "http%3A%2F%2Fwww.example.com%2Fq%3D%E6%98%A5%E8%8A%82"
В приведенном выше коде encodeURIComponent() экранирует метасимволы URL-адреса, поэтому, если вы закодируете весь URL-адрес, вы получите ошибку.
3. декодироватьURI() 4. декодироватьURIкомпонент()
3 и 4 - операции, обратные 1 и 2
3 Каковы общие свойства и методы экземпляра объекта URL?
var url = new URL('http://www.example.com:4097/path/a.html?x=111#part1');
url.href
// "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1"
url.pathname
// "/path/a.html"
url.search
// "?x=111"
Обычно используются статические методы:
- URL.createObjectURL()
Я сам часто использую этот API для локального предварительного просмотра изображений. Следующий случай
<body>
<div id="display" />
<input type="file" id="fileElem" multiple accept="image/*" onchange="handleFiles(this.files)">
<script>
var div = document.getElementById('display');
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var img = document.createElement('img');
console.log(window.URL.createObjectURL(files[i]))
img.src = window.URL.createObjectURL(files[i]);
div.appendChild(img);
}
}
</script>
</body>
Обратите внимание, что каждый раз, когда используется метод URL.createObjectURL, в памяти создается экземпляр URL. Если строка URL-адреса, сгенерированная этим методом, больше не нужна, для экономии памяти вы можете использовать метод URL.revokeObjectURL() для освобождения экземпляра.
- URL.revokeObjectURL()
Метод URL.revokeObjectURL используется для освобождения экземпляра URL-адреса, сгенерированного методом URL.createObjectURL. Его параметром является строка URL, возвращаемая методом URL.createObjectURL.
Следующее добавляет URL.revokeObjectURL() к примеру в предыдущем абзаце.
var div = document.getElementById('display');
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var img = document.createElement('img');
img.src = window.URL.createObjectURL(files[i]);
div.appendChild(img);
img.onload = function() {
window.URL.revokeObjectURL(this.src);
}
}
}
Точка знаний 11 Объект Blob? (Ссылка на подробности)
Конструктор Blob принимает два параметра. Первый параметр — это массив, элементами которого являются строки или двоичные объекты, представляющие содержимое только что сгенерированного объекта экземпляра Blob; второй параметр является необязательным и является объектом конфигурации. В настоящее время существует только один тип атрибута, и его значение — Строка, представляющая MIME-тип данных. По умолчанию это пустая строка.
var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>'];
var myBlob = new Blob(htmlFragment, {type : 'text/html'});
1 Как экземпляр объекта Blob хранит JSON?
Примеры следующие:
var obj = { hello: 'world' };
var blob = new Blob([ JSON.stringify(obj) ], {type : 'application/json'});
2 Что такое файловый объект? (Подробности)
File
Объект представляет файл и используется для чтения и записи информации о файле. он наследуетBlob
предмет или спец.Blob
объект, все могут использоватьBlob
Предметы можно использовать в любом случае.
В приведенном ниже коде файл — это первый файл, выбранный пользователем, который является экземпляром File.
// HTML 代码如下
// <input id="fileItem" type="file">
var file = document.getElementById('fileItem').files[0];
file instanceof File // true
3 Что такое объект FileReader?
FileReader
объект для чтенияFile
объект илиBlob
Содержимое файла, содержащегося в объекте.
Браузер изначально предоставляет конструктор FileReader для создания экземпляров FileReader.
var reader = new FileReader();
Обычно используемые FileReaders имеют следующие свойства экземпляра
- FileReader.result: содержимое файла после завершения чтения, которое может быть строкой или экземпляром ArrayBuffer.
- FileReader.onload: функция прослушивания события загрузки (операция чтения завершена), обычно атрибут результата используется в этой функции для получения содержимого файла.
Ниже приведен пример прослушивания события загрузки.
// HTML 代码如下
// <input type="file" onchange="onChange(event)">
function onChange(event) {
var file = event.target.files[0];
var reader = new FileReader();
reader.onload = function (event) {
console.log(event.target.result)
};
reader.readAsText(file);
}
Более важные методы экземпляра FileReader.
- FileReader.readAsDataURL(): после завершения чтения
result
свойство вернетData URL
Формат(Base64 编码
) строка, представляющая содержимое файла. Для файлов изображений эта строка может использоваться для<img>
элементальsrc
Атрибуты. Обратите внимание, что эта строка не может быть декодирована в Base64 напрямую, она должна иметь префиксdata:*/*;base64
, после удаления из строки, а затем декодирования. - FileReader.readAsText(): после завершения чтения свойство результата вернет текстовую строку содержимого файла. Первым параметром этого метода является файл
Blob
Например, второй параметр является необязательным и указывает на кодировку текста, по умолчаниюUTF-8
.
Ниже приведен пример.
/* HTML 代码如下
<input type="file" onchange="previewFile()">
<img src="" height="200">
*/
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener('load', function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
Точка знаний 12 Объект FormData? (Ссылка на подробности)
Blob
Конструктор принимает два параметра. Первый параметр — это массив, членами которого являются строки или двоичные объекты, представляющие вновь сгенерированныеBlob
Содержимое экземпляра объекта; второй параметр является необязательным и представляет собой объект конфигурации, который в настоящее время имеет только одно свойство.type
, значение которого представляет собой строку, представляющую данныеMIME
Тип, по умолчанию пустая строка.
1 Экземпляры объектов FormData, каковы наиболее часто используемые методы?
- FormData.append(key, value): добавьте пару ключ-значение. Если имя ключа повторяется, будут созданы две пары ключ-значение с одинаковым именем ключа. Если вторым параметром является файл, вы также можете использовать третий параметр, представляющий имя файла.
- FormData.set(key, value): Установите значение ключа указанного имени ключа, параметром является имя ключа. Если имя ключа не существует, будет добавлена пара значений ключа, в противном случае значение ключа с указанным именем ключа будет обновлено. Если вторым параметром является файл, вы также можете использовать третий параметр, представляющий имя файла.
- FormData.delete(key): удалить пару ключ-значение, параметром является имя ключа.
- FormData.get(key): получить значение ключа, соответствующее указанному имени ключа, параметром является имя ключа. Если имеется несколько пар ключ-значение с одинаковым именем, возвращается ключ-значение первой пары ключ-значение.
- FormData.getAll(key): возвращает массив, представляющий все значения ключа, соответствующие указанному имени ключа. Если есть несколько пар ключ-значение с одинаковым именем, массив будет содержать все ключи-значения.
Дело в следующем:
var formData = new FormData();
// 设置某个控件的值
formData.set('username', '张三');
formData.get('username') // "张三"
formData.set('username', '张三');
formData.append('username', '李四');
formData.get('username') // "张三"
formData.getAll('username') // ["张三", "李四"]
formData.append('userpic[]', myFileInput.files[0], 'user1.jpg');
formData.append('userpic[]', myFileInput.files[1], 'user2.jpg');
2 Что такое атрибут enctype и каковы его значения? (Подробности)
Формы могут использовать четыре кодировки для отправки данных на сервер. Формат кодирования определяется атрибутом enctype формы.
(1) метод ПОЛУЧИТЬ
Если форма отправляет данные методом GET, атрибут enctype не действует.
<form
action="register.php"
method="get"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
Данные будут отправлены в виде строки запроса URL.
?foo=bar&baz=The%20first%20line.%0AThe%20second%20line.
(2) application/x-www-form-urlencoded
Если форма отправляет данные методом POST, а атрибут enctype опущен, данные отправляются в формате application/x-www-form-urlencoded (по умолчанию).
<form
action="register.php"
method="post"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
Отправленный HTTP-запрос выглядит следующим образом.
Content-Type: application/x-www-form-urlencoded
foo=bar&baz=The+first+line.%0D%0AThe+second+line.%0D%0A
В приведенном выше коде %0D%0A в теле данных представляет символ новой строки (\r\n).
(3) текстовый/обычный
Если форма отправляет данные, используя метод Post, и атрибут enctype - это текст / просто, то данные будут отправлены в простой тексте.
<form
action="register.php"
method="post"
enctype="text/plain"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
Отправленный HTTP-запрос выглядит следующим образом.
Content-Type: text/plain
foo=bar
baz=The first line.
The second line.
(4) multipart/form-data
Если форма использует метод POST и атрибут enctype имеет значение multipart/form-data, данные будут отправлены в смешанном формате.
<form
action="register.php"
method="post"
enctype="multipart/form-data"
onsubmit="AJAXSubmit(this); return false;"
>
</form>
Отправленный HTTP-запрос выглядит следующим образом.
Content-Type: multipart/form-data; boundary=---------------------------314911788813839
-----------------------------314911788813839
Content-Disposition: form-data; name="foo"
bar
-----------------------------314911788813839
Content-Disposition: form-data; name="baz"
The first line.
The second line.
-----------------------------314911788813839--
Этот формат также является форматом для загрузки файлов.