Серия статей:
- [Младший брат, ты хочешь знать о кросс-доменном] JSONP
- [Брат, ты хочешь знать о кросс-доменном] Основы CORS
- [Брат, ты хочешь узнать о междоменных ресурсах] Расширенные статьи CORS
- [Брат, ты хочешь знать о кросс-доменном] обратном прокси NGINX
- [Брат, ты хочешь знать о кросс-доменном] ServerProxy
существуетпредыдущий пост, мы вместе изучили первую схему междоменной обработки
JSONP
Этот способ относительно примитивен, а преимущество в том, что у него хорошая совместимость, и даже современные фронтенды о нем не слышали.IE 6
На нем можно запускать, но у него есть одно преимущество, а недостатки: поддержка только GET-запросов, сложная настройка (фронт и бэкенд требует корректировки кода), прописывание различных callback-функций на окно, разработка Bad опыт....
CORS
Поскольку решение JSONP имеет много недостатков и устарело, здесь мы изучим более современное решение междоменных проблем --- CORS
совместимость
Список совместимости, склеенный с официального сайта mdn, выглядит следующим образом:
т.е. может работать 10, что достаточно для удовлетворения потребностей современных разработчиков интерфейса.
Концепция 😳
концептуальная вещьздесьMDN иногда требуется лестница, так что принесите свою.
Создайте междоменную среду
Сначала мы создаем междоменную среду, код основан на нашем примере проекта, когда jsonpcross-domain, во-первых, создайте каталог cors в каталогах fe и be. Во-вторых, добавьтеindex.html
а такжеindex.js
, Модифицированный каталог проекта показан ниже.
написать интерфейсный кодfe/cors/index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>CORS 实现跨域</title>
</head>
<body>
<h3>CORS 实现跨域</h3>
<script>
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://localhost:8888')
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
xhr.send()
</script>
</body>
</html>
Очень простой запрос ajax, нет никого.
внутренний кодbe/cors/index.js
const http = require('http');
const PORT = 8888;
// 创建一个 http 服务
const server = http.createServer((request, response) => {
response.end("{name: 'quanquan', friend: 'guiling'}");
});
// 启动服务, 监听端口
server.listen(PORT, () => {
console.log('服务启动成功, 正在监听: ', PORT);
});
В настоящее времякод проекта
искать знаки
После подготовки среды кода
- Сначала запустите внутренний код
node ./be/cors/index.js
- Затем запустите интерфейсный веб-контейнер.
live-server ./fe/cors
- открыть браузер, посетитьhttp://localhost:8080/
- Откройте консоль, перейдите на вкладку Консоль
- обновите свой браузер
Давайте подробно разберем эту знакомую ошибку.В предыдущем абзаце нам сказали, что наш запрос заблокирован.Последний фактически подсказал нам решение напрямую, решение'Access-Control-Allow-Origin' header is present on the requested resource.
, такой очевидный намек, почему бы не попробовать???
Добавьте Access-Control-Allow-Origin в заголовок ответа.
В ответ на ошибку браузера мы проанализировали, что он хотел, чтобы мы добавили в заголовок ответаAccess-Control-Allow-Origin
это поле,
Затем мы модифицируем наш внутренний код.
const http = require('http');
const PORT = 8888;
// 创建一个 http 服务
const server = http.createServer((request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.end("{name: 'quanquan', friend: 'guiling'}");
});
// 启动服务, 监听端口
server.listen(PORT, () => {
console.log('服务启动成功, 正在监听: ', PORT);
});
модифицированныйкод.
Обновите браузер, я хороший мальчик. Хорошо 😄
Обрадовавшись, давайте подумаем, недостаток jsonp в том, что он может поддерживать только запросы GET, т.к.现代
Метод междоменного запроса. Может ли cors поддерживать другие методы запроса?
Поддержка других методов запроса
так как现代
Решение междоменной проблемы должно уметь решать различные методы запроса. Просто говорите и не занимайтесь фальшивыми трюками. Давайте попробуем 😄
Изменить интерфейсный код
// 改动前
xhr.open('GET', 'http://localhost:8888')
// 改动后
xhr.open('POST', 'http://localhost:8888')
после модификациикодПроверить в браузере?
Проблем нет, возвращаемые данные печатаются плавно, ошибок нет.
попробуйPUT
просить
Снова измените интерфейсный код
// 改动前
xhr.open('POST', 'http://localhost:8888')
// 改动后
xhr.open('PUT', 'http://localhost:8888')
после модификациикодПроверить в браузере?
О, мама? Это очень знакомая ошибка, но не признавайте не того человека. Ошибка, о которой сообщается на этот раз, очень похожа на предыдущую, но ключевые слова другие. Основываясь на предыдущем опыте, серверная часть добавилаAccess-Control-Allow-Methods
Заголовки ответов должны работать нормально.
внутренний код
const http = require('http');
const PORT = 8888;
// 创建一个 http 服务
const server = http.createServer((request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Methods', 'PUT');
response.end("{name: 'quanquan', friend: 'guiling'}");
});
// 启动服务, 监听端口
server.listen(PORT, () => {
console.log('服务启动成功, 正在监听: ', PORT);
});
после модификациикодПроверить в браузере?
это сработало 😄
другие методы http иPUT
Способ обработки метода тот же.
Бэкэнд говорит, что вам нужно добавить токен к вашему запросу.
Поскольку это современная разработка, управление сеансом обычно будет использовать jwt (последующие действия могут написать соответствующие статьи), jwt добавлен сияющий символ заголовка запроса jwt token, Мин не сказал темных слов.
Измените внешний код:
// 添加了一行
xhr.setRequestHeader('token', 'quanquanbunengshuo')
после модификациикодПроверить в браузере?
Я считаю, что все разобрались с моим распорядком, никаких сплетен.
внутренний код
// 添加了一行
response.setHeader('Access-Control-Allow-Headers', 'token');
после модификациикодПроверить в браузере?
До сих пор междоменный запрос был успешным, метод запроса совместим, а настраиваемый заголовок запроса прост в использовании.Это удача, мы можем есть курицу?
К, закинутая в морозилку вкладка Сеть
Мы проверяли вкладку «Консоль» браузера от начала до конца, и в качестве коммуникационной статьи, очевидно, было бы немного неразумно не смотреть на «Сеть».
Раз он есть, его надо видеть, переключаем вкладку на Сеть.
Привет, два запроса, один OPTIONS и один PUT, что это за хрень?
Превью следующего эпизода: Был кровавый случай сразу после того, как я увидел Сеть.Конечно, если просто остаться на кроссдоменной реализации с CORS, пока проблем нет.Это также пощечина для интервью. Далее давайте рассмотрим условие CORS,预检请求
а такжеCookie
Носи эти вещи, я чувствую себя таким утомительным, чтобы писать код в пятницу... Попроси даму поострее 😄