Углубленные междоменные проблемы (4) - Использование прокси для решения междоменных проблем

Node.js внешний интерфейс сервер

читать оглавление

Углубленная междоменная проблема (1) — первое понимание междоменного совместного использования ресурсов CORS;

Углубленные междоменные проблемы (2) — Использование CORS для решения междоменных проблем

Глубокая междоменная проблема (3) — Использование JSONP для решения междоменной проблемы

Углубленная междоменная проблема (4) — используйте прокси-сервер для решения междоменной проблемы (эта статья)

Таким образом, в приведенной выше статье мы узнали, что,CORS,JSONPСуществует два способа реализации междоменных запросов.

Оба метода требуют, чтобы передняя и задняя стороны взаимодействовали, чтобы иметь возможность правильно решать междоменные проблемы.Сегодня я представлю метод, который не требует взаимодействия между интерфейсом и сервером, а интерфейс можно выполнить самостоятельно.

Как мы все знаем,Политика того же происхождения — это стандарт, которому должны следовать браузеры., Дело в томбраузер, если это сервер, то не надо ли его соблюдать? ? ?

NODE как клиент

Это одно из наших предположений. Нет необходимости следовать политике одного и того же происхождения между браузерами, не являющимися браузерами. Давайте сначала проверим это:

NODE отправляет метод POST

Клиент:

const http = require('http');

const options = {
    hostname: '127.0.0.1',      // 注意这里不要添加 http 前缀
    port: 4000,     // 服务器端口号
    path: '/',      // 访问路径
    method: 'POST',
    headers: {
        'Content-Type': 'application/json;charset=utf-8',
    }
};

const request = http.request(options, (serverResponse) => {

    var body = '';

    serverResponse.on('data', (chunk) => {
        body += chunk;
    });

    serverResponse.on('end', () => {
        console.log('The data is ' + body);
    })

});

request.end();

Сервер инициирует запрос POST

PS: Под методом POST в браузереContent-Typeдляapplication/json;, вызоветпредварительный запрос(см. мою предыдущую статью).

сервер:

const http = require('http');

const data = { name: 'BruceLee', password: '123456' };

const server = http.createServer((request, response) => {

    if (request.url === '/') {
        response.end( JSON.stringify(data) );
    }
    
});

server.listen(4000, () => {
    console.log('The server is running at http://localhost:4000');
});

Примечание. Мы не добавили какие-либо поля заголовков, используемые совместно с ресурсами CORS с разными источниками внутри сервера.

Результаты экспериментов:

Результаты испытаний показывают, чтоNODEИнициировать запрос, чтобы избежатьбраузерполитика того же происхождения.

прокси-сервер

Прокси-сервер требует следующих шагов:

  1. принять клиентапросить.
  2. Будупроситьперенаправлены на сервер.
  3. получить сервероткликданные.
  4. Будуоткликпереданы клиенту.

Это простой текстовый анализ, и следующий схематический процесс:

Это рабочий механизм прокси-сервера (PS: фигня нарисованная, хахаха).

Реализовать прокси-сервер

После понимания механизма работы прокси-сервера мы будем использовать NODE для реализации прокси-сервера.

Клиент:

<!DOCTYPE html>
<html lang="zh-CN">

<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>Ajax测试</title>
</head>
     
<body>
    
    <script src="./node_modules/jquery/dist/jquery.min.js"></script>

    <script>
    var data = { name: 'BruceLee', password: '123456' };

    $.ajax({
        url: "http://localhost:3000",
        type: "post",
        data: JSON.stringify(data),
        contentType: 'application/json;charset=utf-8',
        success: function (result) {
            console.log(result);
        },
        error: function (msg) {
            console.log(msg);
        }
    })
    </script>
</body>

</html>

Точно так же вы можете заменить его такими методами, как PUT, DELETE и т. д. для тестирования.

Прокси-сервер: 3000 порт

const http = require('http');

// 第一步:接受客户端请求
const server = http.createServer((request, response) => {
	
    // 代理服务器,直接和浏览器直接交互,也需要设置:CORS 的首部字段
    response.writeHead(200, {
        'Access-Control-Allow-Origin': '*',  // 设置 optins 方法允许所有服务器访问 
        'Access-Control-Allow-Methods': '*',
        'Access-Control-Allow-Headers': 'Content-Type',
    });
	
    // 第二步:将请求转发给服务器
    const proxyRequest = http.request({
        host: '127.0.0.1',
        port: 4000,
        url: '/',
        method: request.method,
        headers: request.headers
    }, (serverResponse) => {
        
        // 第三步:收到服务器的响应
        var body = '';

        serverResponse.on('data', (chunk) => {
            body += chunk;
        });

        serverResponse.on('end', () => {
            console.log('The data is ' + body );
            
            // 第四步:将响应结果转发给浏览器
            response.end(body);
        })

    }).end();

});

server.listen(3000, () => {
    console.log('The proxyServer is running at http://localhost:3000');
});

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

Сервер: порт 4000

const http = require('http');

const data = { name: 'BruceLee', password: '123456' };

const server = http.createServer((request, response) => {

    if (request.url === '/') {
        response.end( JSON.stringify(data) );
    }

});
 
server.listen(4000, () => {
    console.log('The server is running at http://localhost:4000');
});

Чтобы не занимать много места, я использовал относительно краткий код, вы можете попробовать больше для себя, например: методы PUT, DELETE.

Результаты экспериментов:

Успешно предотвращены запросы из разных источников.

Теперь все готово, прокси-сервер решает междоменную проблему и не требует никаких настроек в фоновом режиме.

Ссылки и благодарности

Прокси-сервер — распространенное средство современного интерфейса, помимо обратного прокси-сервера и многих других способов выполнения междоменных запросов.