Когда я недавно работал над музыкальным веб-приложением, я столкнулся с таким требованием:Извлеките цвет темы изображения песни, а затем примените его к глобальному.
Первоначальная идея состоит в том, чтобы нарисовать изображение на холсте и использовать getImageData() для получения данных о пикселях изображения и анализа данных для получения цвета, наиболее близкого к изображению. Тогда возникает проблема: если рисовать междоменные ресурсы в канвасе, то канвас будет загрязнён и вызов метода будет невозможен (т.к. все данные захвачены на официальном сайте QQ Music). Говоря об этом, давайте поговорим о внешнем междоменном интерфейсе.
Если вам интересен проект, нажмите здесь 👉адрес проекта
что такое кросс домен
Как правило, когда URL-адрес запросаПротокол, доменное имя, портЛюбой из трех, отличающийся от адреса текущей страницы, является междоменным. Наиболее распространенным является вызов ресурсов в другом доменном имени на веб-странице под одним доменным именем.
Когда браузер сообщает о такой ошибке, возникает проблема с междоменным запросом.
Почему междоменный
В основном в целях безопасности браузеры используют политику одного и того же источника для ограничения js, чтобы предотвратить получение злоумышленниками незаконных данных, а также предотвратить большинство XSS-атак (то есть внедрение js-скриптов в пользовательский интерфейс).
Политики одного и того же источника двух браузеров могут вызвать проблемы с разными источниками:
- Политика гомологии DOM. Запрещено оперировать DOM страниц разного происхождения, в основном включая iframe, canvas и им подобные. Если фреймы из разных источников запрещают взаимодействие с данными, холсты, содержащие данные из разных источников, будут загрязнены и не смогут работать.
- XmlHttpRequest Та же политика происхождения. Проще говоря, AJAX-запросы из разных источников запрещены, в основном для предотвращения CSRF-атак.
Почему браузер сообщает об ошибке при междоменном
Это связано с тем, что W3C ввел стандарт — «Совместное использование ресурсов между источниками» (сокращенно CORS). Этот стандарт определяет, как серверы и браузеры взаимодействуют при доступе к ресурсам в разных доменах. С точки зрения непрофессионала, когда браузер обнаруживает междоменный запрос, онДобавить некоторую информацию заголовкаСвяжитесь с сервером, чтобы определить, пройдет ли междоменный запрос.Теперь все браузеры, кроме IE10 и ниже, поддерживают этот стандарт..
Браузеры делят кросс-оригинальные запросы на две категории: простые и непростые запросы.
простой запрос
Простые запросы имеют следующие характеристики:
- Метод запроса является одним из следующих
- GET
- POST
- HEAD
- информация заголовка является одним из следующих полей
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type // Тип поля не может быть application/json
Те, которые удовлетворяют одновременно двум вышеуказанным пунктам, являются простыми запросами, а остальные — непростыми запросами.
Когда браузер распознает междоменный запрос как простой запрос, он добавитOriginполе, которое будет ссылаться на источник этого запроса(протокол, доменное имя, порт)Принесите его на сервер, и сервер проверит источник запроса.
если серверсогласнаЧто касается этого источника, то он, нормально отвечая браузеру, такжедополнительныйПоследние несколько полей возвращаются:
- Access-Control-Allow-Origin // Это источник, с которым соглашается служба, или "*" для всех источников.
- Access-Control-Allow-Credentials // Это говорит о том, что браузер может отправлять файлы cookie
В общем, он был распознан сервером, так что браузер может нормально получить ответ.
еслине согласен, сервер возвращает данные нормально, ничего не прикрепляется, и браузер его не видитAccess-Control-Allow-OriginОн будет недоволен, а потом не отдаст вам возвращенные данные, а потом сообщит об ошибке, которая аналогична вышеописанной (то есть при извлечении цвета цветовой темы 😡). А код статуса еще разный, может быть даже 200😫
не простой запрос
Такой непростой запрос, например запрос PUT или DELETE, также имеет тип поля Content-Type, равный
приложение/json. Браузер будет строже.Перед отправкой междоменного запроса он отправит запрос "pre-check" чтобы посмотреть отношение сервера.Этот запрос pre-check особенный.Метод запроса называетсяOPTIONS, информация заголовка не только содержитOriginТакже есть два поля:
- Access-Control-Request-Method // Это сообщает серверу, что такое междоменный запрос.
- Access-Control-Request-Headers // Это дополнительная информация, которая будет добавлена, когда браузер делает междоменный запрос
После того, как сервер получит информацию, отправленную предварительным запросом, он будет более строгим, проверяя не только источник, но также метод запроса и поля заголовка.
если серверсогласна, просто добавьте его к обычному ответу HTTPAccess-Control-Allow-Originполе, в котором также указан источник согласия службы.
Это означает, что он был одобрен сервером, ведь он прошел строгую проверку.каждый разЗапросы между источниками будут работать нормально.
еслине согласен, сервер тоже нормально отвечает без всяких доп, на этот раз браузер его не видитAccess-Control-Allow-OriginНо я буду злиться, я даже не удосуживаюсь отправлять междоменные запросы, а прямо сообщать об ошибке. (Если эта ситуация не встречалась, она не будет изображена).
Так говорят, что ошибка вызвана браузером.
Как решить междоменные проблемы
Кроссдоменные проблемы часто встречаются в повседневной разработке, давайте рассмотрим распространенные решения:
1.JSONP
Такие теги, как img и script, не имеют междоменных ограничений, поэтому программисты придумали способ динамического создания тегов script и использования атрибута src для источника междоменных запросов.
function fun(data) {
console.log(data);
};
var body = document.getElementsByTagName('body')[0];
var script = document.gerElement('script');
script.type = 'text/javasctipt';
script.src = 'http://example.com?jsonp=cb';
body.appendChild(script);
Возвращенный js-скрипт будет выполнен напрямую, так что нужные нам данные будут переданы.
Этот метод совместим со всеми браузерами, и интерфейс может легко делать междоменные запросы, но он также имеет некоторые недостатки:
- Его можно запросить только через GET, с одной стороны длина параметров ограничена, а с другой безопасность относительно плохая;
- Серверной части необходимо знать, какова структура внешнего интерфейса cb, в основном в параметрах и именах обратных вызовов;
- Бэкенд должен соединить параметры и cb, прежде чем его можно будет выполнить;
Требование этой статьи - нарисовать картинку на холсте, этот способ не подойдет, смотрите следующий
2. Прокси-сервер
Сервер не имеет междоменных ограничений, как браузеры.Сервер может запрашивать междоменные ресурсы, а затем возвращать их клиенту.Возьмите холст для работы с междоменными изображениями.Клиент отправляет междоменный URL-адрес на сервер и запрашивает изображение. Затем отправьте его обратно клиенту, вы можете решить проблему, упомянутую в начале (код выше~)
Картинка передается в протоколе http в виде бинарного потока, поэтому обязательно обратите внимание на формат кодировки, иначе вернет кучу вещей, о которых вы не знаете, что это такое.
Сначала запустите экспресс-сервис в фоновом режиме, где запрос на получение использует пакет https в npm.
apiRoutes.get('/image', function (req, res) {
const Url = (req.query)['0'];
https.get(Url, function (response) {
response.setEncoding('binary'); //二进制binary
var type = response.headers["content-type"];
let Data = '';
response.on('data', function (data) { //加载到内存
Data += data;
}).on('end', function () { //加载完
res.writeHead(200, { 'Access-Control-Allow-Origin': '*', "Content-Type": type }); //设置头,允许跨域
res.end(new Buffer(Data, 'binary'));
})
})
});
app.use('/api', apiRoutes)
Затем отправьте URL-адрес междоменного изображения на этот маршрут, и вы сможете «замаскировать» его под гомологичное изображение.
http://example.com/api/image?0=(跨域的图片url)
—————————————— Обновление 11.17 ———————————————————
Извлечение цвета темы здесь 👉Извлечение цвета темы
Вышеупомянутая статья опубликована на этот раз, добро пожаловать, чтобы оставить сообщение, чтобы учиться друг у друга~