2017-10-20 101 views
0

我在nodejs中創建了本地REST API服務器,它從本地Mongodb數據庫獲取數據。我還創建了一個基本網頁,它從本地請求服務器的數據。現在,當我嘗試從網頁中獲取數據,它給了我以下錯誤:無法在本地Nodejs服務器中允許跨域請求

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:4000/todos. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). 

我搜索關於計算器,發現THISTHIS解決方案。我在我的主app.js文件中添加了建議的標題。但它仍然給出了同樣的錯誤。

以下是我的服務器app.js文件,我添加了這些標頭。

var express = require('express'); 
var path = require('path'); 
var favicon = require('serve-favicon'); 
var logger = require('morgan'); 
var cookieParser = require('cookie-parser'); 
var bodyParser = require('body-parser'); 

var routes = require('./routes/index'); 
var users = require('./routes/users'); 
var todos = require('./routes/todos'); 

// load mongoose package 
var mongoose = require('mongoose'); 

// Use native Node promises 
mongoose.Promise = global.Promise; 

// connect to MongoDB 
mongoose.connect('mongodb://localhost/todo-api') 
.then(() => console.log('connection succesful')) 
.catch((err) => console.error(err)); 

var app = express(); 

// view engine setup 
app.set('views', path.join(__dirname, 'views')); 
app.set('view engine', 'ejs'); 

// uncomment after placing your favicon in /public 
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 
app.use(logger('dev')); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })); 
app.use(cookieParser()); 
app.use(express.static(path.join(__dirname, 'public'))); 

app.use('/', routes); 
app.use('/users', users); 
app.use('/todos', todos); 

// Add headers 
app.use(function (req, res, next) { 

    // Website you wish to allow to connect 
    res.setHeader('Access-Control-Allow-Origin', '*'); 

    // Request methods you wish to allow 
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); 

// Request headers you wish to allow 
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); 

// Set to true if you need the website to include cookies in the requests sent 
// to the API (e.g. in case you use sessions) 
res.setHeader('Access-Control-Allow-Credentials', true); 

// Pass to next layer of middleware 
next(); 
}); 
// catch 404 and forward to error handler 
    app.use(function(req, res, next) { 
    var err = new Error('Not Found'); 
    err.status = 404; 
    next(err); 
}); 

// error handlers 

// development error handler 
// will print stacktrace 
if (app.get('env') === 'development') { 
    app.use(function(err, req, res, next) { 
    res.status(err.status || 500); 
    res.render('error', { 
     message: err.message, 
     error: err 
    }); 
    }); 
} 

// production error handler 
// no stacktraces leaked to user 
app.use(function(err, req, res, next) { 
    res.status(err.status || 500); 
    res.render('error', { 
    message: err.message, 
    error: {} 
    }); 
}); 

module.exports = app; 

以下是網頁的代碼(Angularjs),我想從我的API中獲取數據。

dbConnection.html

<html ng-app="demo"> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"> </script> 
<head> 
    <title> dbConnection Demo</title> 
</head> 

<body ng-controller="db"> 
    <div ng-repeat="product in db.products"> 
     {{product._id}} </br> 
    </div> 
</body> 

<script> 
    var app = angular.module('demo', []); 
    app.controller('db', ['$http', function($http){ 
     var store = this; 
     store.products = []; 

     $http({ 
      method: 'GET', 
      url: 'http://localhost:4000/todos' 
      }).then(function (success){ 
       store.products = success; 
      },function (error){ 

      }); 
    }]); 
</script> 
</html> 

即使我已經添加標題作爲答案的建議,我得到了同樣的錯誤。我在這裏錯過了什麼?我在這個領域是完全新手。謝謝!

+0

嘗試[CORS中間件](https://github.com/expressjs/cors) –

+0

沒關係,但在哪裏使用它? – Kaushal28

+0

鏈接中的[documentation](https://github.com/expressjs/cors#usage)對此進行了徹底的解釋。 –

回答

0

我終於想通過在我的路線中添加這些標題來解決問題,如下所示:

routes/todos.js

... 
... 
router.get('/', function(req, res) { 
res.setHeader('Access-Control-Allow-Origin', '*'); 
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed 
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,contenttype'); // If needed 
res.setHeader('Access-Control-Allow-Credentials', true); // If needed 

res.send('cors problem fixed:)'); 
}); 
0

您可能必須添加:

res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 

爲什麼?那麼我認爲我有同樣的問題,這解決了我的問題。

+0

我已經刪除以前的方法後添加此行? – Kaushal28

+0

它給出了相同的錯誤 – Kaushal28

0

請移動標題代碼var app = express(); 這意味着您必須將它們放置在定義路由器之前。

var app = express(); 
app.use(function (req, res, next) { 

// Website you wish to allow to connect 
res.setHeader('Access-Control-Allow-Origin', '*'); 

// Request methods you wish to allow 
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); 

// Request headers you wish to allow 
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); 

// Set to true if you need the website to include cookies in the requests sent 
// to the API (e.g. in case you use sessions) 
res.setHeader('Access-Control-Allow-Credentials', true); 

// Pass to next layer of middleware 
next(); 
}); 

// Router 
+0

請參閱代碼。我的'app.js'。 – Kaushal28

+0

我的意思是你必須把它放在路由器之前 –

1

您的要求是否需要預飛機響應?如果確實如此,它會嘗試用'OPTIONS'方法擊中你的端點,除非你設置了一個,否則你會看到cors問題。

因此,如果您發現預檢響應失敗,您可以添加自定義選項的路線,或潛在用途故宮CORS包 - https://www.npmjs.com/package/cors

npm install cors --save 

在你app.js

var cors = require('cors') 


app.options('*', cors()) // include before other routes 
app.use(cors())