Я запускаю сервер NodeJS, который обслуживает пользовательский интерфейс со встроенной папкой Angular / dist.

В пользовательский интерфейс я включаю swagger-ui, который загружает swagger.json, * .json описывает интерфейс REST, а в swagger-ui вы должны иметь возможность тестировать интерфейсы REST.

https://swagger.io/swagger-ui/

Структура проекта

enter image description here

В server.js я добавил фиксированный маршрут к пути / dist, где хранится index.html, а также есть экспресс-маршруты к остальным интерфейсам, которые предлагает мой сервер. для загрузки файлов документации swagger.json

Server.js

// Get dependencies
const dotEnv      = require('dotenv').config();
const express     = require('express');
const path        = require('path');
const http        = require('http');
const bodyParser  = require('body-parser');
var mongoose      = require('mongoose');
const cors        = require('cors');
// Get our API routes
const api         = require('./server/routes/api');
const swaggerAPI  = require('./server/routes/swaggerAPI');
const app         = express();


var connectionUrl = typeof process.env.CONNECTION_URL  !== 'undefined' ?  process.env.CONNECTION_URL  : 'mongodb://db:27017/docdb';
console.log("Connection URL: " + connectionUrl);
mongoose.connect(connectionUrl);

// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));

// Set our api routes
app.use('/api', api);
app.use('/swagger-api', swaggerAPI);

app.use('/client', express.static('client'));

app.use(cors());
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
    res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
    if ('OPTIONS' === req.method) {
        res.status(204).send();
    }
    else {
        next();
    }
});

// Catch all other routes and return the index file
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
});

/**
 * Get port from environment and store in Express.
 */
const port = process.env.PORT || '3000';
app.set('port', port);

/**
 * Create HTTP server.
 */
const server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */
app.listen(port, () => console.log(`API running on localhost:${port}`));

Все работает нормально. Я могу загрузить swagger.json своими интерфейсами REST, сохранить их в MongoDB и показать их в пользовательском интерфейсе Angular. Но когда я хочу протестировать интерфейсы REST из swagger-ui, я получаю сообщение об ошибке в консоли:

 Failed to load http://localhost:8888/****/Y7CTQW5PTSEG1MMPN: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Но когда я отлаживаю запрос в Chrome, я вижу загруженные данные на вкладке «Сеть».

Почему консоль показывает ошибку cors при загрузке данных и не отображает их в пользовательском интерфейсе?

0
Andreas Vitzthum 15 Мар 2018 в 12:54

1 ответ

Лучший ответ

Когда сайт A пытается получить контент с сайта B, сайт B может отправить заголовок ответа Access-Control-Allow-Origin, чтобы сообщить браузеру, что содержимое этой страницы доступно для определенных источников. (Источник - это домен, плюс схема и номер порта.) По умолчанию страницы сайта B недоступны для любого другого источника; использование заголовка Access-Control-Allow-Origin открывает дверь для доступа между разными источниками для определенных запрашивающих источников.

Для каждого ресурса / страницы, которые сайт B хочет сделать доступным для сайта A, сайт B должен обслуживать свои страницы с заголовком ответа:

Access-Control-Allow-Origin: http://siteA.com Современные браузеры не блокируют междоменные запросы напрямую. Если сайт A запрашивает страницу с сайта B, браузер фактически получит запрошенную страницу на сетевом уровне и проверит, указан ли в заголовках ответа сайт A как разрешенный домен запрашивающей стороны. Если сайт B не указал, что сайту A разрешен доступ к этой странице, браузер вызовет событие ошибки XMLHttpRequest и отклонит данные ответа на запрашивающий код JavaScript.

Предположим, что сайт A хочет отправить запрос PUT для / somePage с непростым значением Content-Type application / json, браузер сначала отправит предварительный запрос:

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

Обратите внимание, что заголовки Access-Control-Request-Method и Access-Control-Request-Headers добавляются браузером автоматически; добавлять их не нужно. Эта предварительная проверка OPTIONS получает заголовки успешного ответа:

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

При отправке фактического запроса (после выполнения предварительной проверки) поведение идентично тому, как обрабатывается простой запрос. Другими словами, непростой запрос, предварительная проверка которого прошла успешно, обрабатывается так же, как простой запрос (то есть сервер все равно должен снова отправить Access-Control-Allow-Origin для фактического ответа).

Браузеры отправляют фактический запрос:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{"myRequestContent": "JSON такой классный"} И сервер отправляет обратно Access-Control-Allow-Origin, как если бы это был простой запрос:

Access-Control-Allow-Origin: http://siteA.com См. Понимание XMLHttpRequest через CORS для получения дополнительной информации о непростых запросах. Пожалуйста, проверьте и эти ссылки, чтобы решить и исправить вашу проблему.

Руководство по содержанию Cors

Использование корса

фиксация корса

0
Neha Tawar 15 Мар 2018 в 13:57