Практика междоменных решений cors и jsonp

задняя часть внешний интерфейс сервер браузер

Узнайте о нескольких междоменных решениях и испытайте их на практике.

Как практиковать?

Но как мы это практикуем? Куда отправить запрос? На какой сервер отправить запрос? Это очень просто, достаточно на текущей веб-странице открыть консоль и ввести запрошенный код

var url = 'http://127.0.0.1:8888/';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();

Затем мы можем использовать текущий URL-адрес страницы в качестве источника для отправкиhttp://127.0.0.1:8888/, отправить запрос GET запрос.
В то же время создайте службу узла локально

var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');
скопировать код

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

ps: веб-сайт github не работает (эта статья изначально была написана на github), это вызовет ошибку csp.Эта ошибка используется для предотвращения атак путем внедрения контента.Надо сказать, что меры безопасности крупных веб-сайтов хорошо сделаны , и они должны перейти к segmentfault для практики.

cors_error

1. cors

cors (совместное использование ресурсов из разных источников), который позволяет браузерам отправлять запросы XMLHttpRequest на серверы из разных источников для преодоления проблем с разными источниками, для этого требуется поддержка как браузера, так и сервера.

Существует два типа запросов cors, простые запросы и непростые запросы.Для более подробного ознакомления с cors я рекомендую Mr. Ruan YifengПодробное объяснение CORS для совместного использования ресурсов между доменами, эта статья посвящена практике.

простой запрос

Как пример выше, это простой запрос

var url = 'http://127.0.0.1:8888/';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();

Как решить междоменную проблему в этом случае?

  1. На стороне браузера браузер автоматически добавит поле происхождения в заголовок запроса, и нам не нужно ничего делать.
Request Headers: 
Origin: https://github.com
скопировать код
  1. Сервер, свойство Access-Control-Allow-Origin, нам нужно, чтобы сервер установил это свойство, чтобы указать разрешенное имя исходного домена запроса, которое можно указать как*указать все доменные имена. Задний конец движется:
var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain',
      'Access-Control-Allow-Origin': '*'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

Перезапустите службу и повторите попытку.

cors_error
На этот раз ошибки больше нет, посмотрим, что вернул сервер
response
Приятно! Междоменный успех!

не простой запрос

Аналогично вводим в консоль код поставить (не простой запрос)

var url = 'http://127.0.0.1:8888/';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.send();

нет неожиданной ошибки

error_image

При выполнении непростого запроса браузер сначала отправит запрос OPTION для «предварительной проверки», разрешен ли запрос, и заголовок запроса будет переданAccess-Control-Request-Method,Access-Control-Request-HeadersЧтобы сообщить серверу методы и поля, которые мне нужно использовать, сервер возвращает информацию заголовка черезAccess-Control-Allow-Origin,Access-Control-Allow-Methodчтобы сообщить браузеру, разрешен ли запрос о перекрестном происхождении. Измените внутренний код:

var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain',
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

Вы можете видеть, что браузер сначала отправит предварительную проверку

option

При подтверждении того, что перекрестный домен разрешен, запрос будет опущен, а процесс предварительного обнаружения будет опущен как простой запрос. Очевидно, что после модифицирована Backend Code, на этот раз запрос на поставку успешен. Это не собирается здесь.

corsСводка

cors (совместное использование ресурсов из разных источников), который позволяет браузерам отправлять запросы XMLHttpRequest на серверы из разных источников для преодоления проблем с разными источниками, для этого требуется поддержка как браузера, так и сервера.

  1. Сторона браузера автоматически добавит поле источника в заголовок запроса, чтобы указать источник текущего запроса.
  2. Сторона браузера должна установить заголовок ответаAccess-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Originи другие поля, укажите разрешенные методы, заголовки, источники и другую информацию.
  3. Запросы делятся на простые запросы и непростые запросы. Непростые запросы сначала выполняют предварительную проверку с помощью метода OPTION, чтобы узнать, разрешен ли текущий междоменный запрос.

2. jsonp

Принцип jsonp заключается в использованииscriptЯрлыки не имеют междоменных ограничений и могут передаваться черезscriptАтрибут src тега отправляетсяGETпросить. Давайте продолжим попытки, сначала удалите междоменные настройки, связанные с серверной частью, и перезапустите службу.

var http = require('http');

http.createServer(function (request, response) {

    response.writeHead(200, {
      'Content-Type': 'text/plain'
    });

    response.end('request success!!!');
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

Откройте нашу консоль и введите код, используйте тег скрипта, чтобы сделать запрос jsonp

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = `http://127.0.0.1:8888/`;
document.head.appendChild(script);

Как вы можете видеть, бэкэнд возвращается нормально

request success !!!

и запросGETпросить

Request URL: http://127.0.0.1:8888/
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:8888
Referrer Policy: no-referrer-when-downgrade

Но мы только что успешно отправили междоменный запрос, но не можем получить данные в res.responseText вроде XMLHttpRequest, как мы можем получить запрошенные данные через jsonp? Метод заключается в том, что внешний и внутренний интерфейс согласовывают имя поля обратного вызова для передачи имени функции, а внешний интерфейс получает данные через эту функцию. Интерфейсный код изменен на:

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = `http://127.0.0.1:8888/?callback=onBack`;
document.head.appendChild(script);
function onBack (res) {
  console.log(JSON.stringify(res));
  // 请求完后删除添加到页面上的script标签
  var head = document.head
  head.removeChild(script)
}

Имя функции onBack передается через поле обратного вызова, а внутренний код изменяется на

var http = require('http')
var urlTool = require('url')
// json 数据
var data = {'methods': 'jsonp', 'result': 'success'};

http.createServer(function (request, response) {
    var params = urlTool.parse(request.url, true)
    console.log(params)
    response.writeHead(200, {
      'Content-Type': 'text/plain'
    });
    if (params.query && params.query.callback) {

      // callback(data)
      var str = `${params.query.callback}(${JSON.stringify(data)})`
    }

    response.end(str);
}).listen(8888);

console.log('Server running at http://127.0.0.1:8888/');

Перезапустите серверную службу и введите код в консоли, вы увидите результат:

jsonp

Мы получили данные и выводим их на консоль через функцию onback!

Суммировать

  1. jsonp — это междоменная схема, использующаяscriptЯрлык не имеет функции междоменного ограничения, черезscriptАтрибут src тега отправляетсяGETпросить.
  2. Имя поля, такое как обратный вызов, может быть согласовано между внешним и внутренним интерфейсом для передачи имени функции, чтобы внешний интерфейс мог использовать соответствующую функцию обратного вызова для получения и обработки данных.

сравнение jsonp и cors

  1. CORS служит той же цели, что и JSONP, но является более мощным, чем JSONP.
  2. JSONP поддерживает только запросы GET, CORS поддерживает все типы HTTP-запросов. Преимущество JSONP в том, что он поддерживает старые браузеры и может запрашивать данные с веб-сайтов, не поддерживающих CORS.

Политика единого источника: политика единого источника ограничивает взаимодействие текста или скриптов, загруженных из одного источника, с ресурсами из других источников.Это важный механизм безопасности для изоляции потенциально вредоносных файлов. Две страницы принадлежат одному и тому же источнику, если они имеют один и тот же протокол, порт (если он указан) и хост.