为SWAN单点应用程序添加cors,用于Swagger-ui

时间:2018-03-15 09:54:35

标签: node.js express cors swagger swagger-ui

我正在运行一个NodeJS服务器,该服务器使用构建的Angular / dist文件夹为UI服务。

在UI中我包含了swagger-ui,它正在加载一个swagger.json,* .json正在描述一个REST接口,并且在swagger-ui中你应该能够测试REST接口。

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

项目结构

enter image description here

在server.js中,我在存储index.html的/ dist路径中添加了一个固定的路由,还有到我的服务器提供的其余接口的快速路由。加载swagger.json文档文件

server.js

* {
margin:0;
padding:0;
}
#nav {
list-style:none;
height:2em;
}
#nav li {
position:relative;
float:left;
width:192px;
background:#999;
text-align:center;
}
#nav li:hover {
background:#777;
}
#nav a {
display:block;
color:#000;
text-decoration:none;
line-height:2em;
}
/* --------- Drop Down -------- */
#nav ul {
position:absolute;
left:-999em;
top:2em;
list-style:none;
}
#nav li:hover ul {
left:0;
top:auto;
}

Everthing工作正常我可以使用我的REST接口加载swagger.json,将它们保存在MongoDB中并在Angular UI中显示它们。 但是,当我想从swagger-ui测试REST接口时,我在控制台中收到错误:

// 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}`));

但是当我在Chrome中调试请求时,我可以在“网络”标签中看到加载的数据。

为什么控制台显示cors错误,同时加载数据而不是在ui中显示?

1 个答案:

答案 0 :(得分:0)

当站点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想要发送/ somePage的PUT请求,使用非简单的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 有关非简单请求的更多信息,请参阅了解基于CORS的XMLHttpRequest。 请检查此链接以解决并解决您的问题。

Cors content tutorial

Using cors

fixing cors