2017-03-26 26 views
3

我正在構建一個完整的堆棧React應用程序,它使用Axios訪問它自己的後端API。在我的本地環境中,以下方式按預期工作,服務器使用JSON數據進行響應,然後正確渲染。使用React訪問內部API,Heroku上的Axios

axios.get('/api/questions/categories') 

我部署到Heroku,並且應用程序正常啓動並且MongoDB已連接。現在,當發出相同的GET請求時,它不會到達後端。當我將Axios的響應記錄到控制檯時,它包含頁面的實際HTML,而不是預期的JSON對象。

爲了進一步說明,如果我在地址欄中手動鍵入'http://localhost:8080/api/questions/categories',則會顯示預期的JSON數據。如果我對Heroku上的應用程序執行相同操作,則會看到'#'被附加到url,並且頁面顯示不會更改,也不會顯示錯誤消息。這導致我認爲反應路由器有問題,但我一直無法弄清楚如何/爲什麼。

我的堆棧:節點,快速,蒙戈,陣營

不使用終極版

使用Axios公司打電話給我自己的API

// Dependencies 
var express = require('express'); 
var path = require('path'); 
var webpack = require('webpack'); 
var webpackMiddleware = require('webpack-dev-middleware'); 
var webpackHotMiddleware = require('webpack-hot-middleware'); 
var config = require('./webpack.config.js'); 
var bodyParser = require('body-parser'); 
var mongoose = require('mongoose'); 
var morgan = require('morgan'); 

var inDev = process.env.NODE_ENV !== 'production'; 
var port = inDev ? 8080 : process.env.PORT; 
var app = express(); 

// MIDDLEWARE 

if (inDev){ 
    var compiler = webpack(config); 
    var middleware = webpackMiddleware(compiler, { 
    publicPath: config.output.publicPath, 
    contentBase: 'app', 
    stats: { 
     colors: true, 
     hash: false, 
     timings: true, 
     chunks: false, 
     chunkModules: false, 
     modules: false 
    } 
    }); 

    app.use(morgan('dev')); 
    app.use(middleware); 
    app.use(webpackHotMiddleware(compiler)); 
    app.get('/', function response(req, res) { 
    res.write(middleware.fileSystem.readFileSync(path.join(__dirname,  'dist/index.html'))); 
    res.end(); 
    }); 
} else { 
    app.use(express.static(__dirname + '/dist')); 
    app.get('*', function response(req, res) { 
    res.sendFile(path.join(__dirname, 'dist/index.html')); 
    }); 
} 

app.use(bodyParser.urlencoded({extended: true})); 
app.use(bodyParser.json()); 

app.use(function(req, res, next) { 
    res.setHeader('Access-Control-Allow-Origin', '*'); 
    res.setHeader('Access-Control-Allow-Credentials', 'true'); 
    res.setHeader('Access-Control-Allow-Methods',  'GET,HEAD,OPTIONS,POST,PUT,DELETE'); 
    res.setHeader('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers'); 

    //and remove caching so we get the most recent comments 
    res.setHeader('Cache-Control', 'no-cache'); 
    next(); 
}); 

// DATABASE 

var dbPath = inDev ? 'mongodb://localhost/quizMe' :  'mongodb://heroku_pmjl5579:[email protected]:43000/heroku_pmjl5579'; 

mongoose.connect(dbPath); 

// ROUTING/API 

// var indexRoute = require('./routes/index'); 
var questionsRoute = require('./routes/api/questions'); 
// app.use('/', indexRoute); 
app.use('/api/questions', questionsRoute); 

app.listen(port, function(){ 
    console.log('Express server up on ' + port); 
}); 

感謝您的幫助!

回答

2

大多數單頁應用程序將所有請求路由到根路徑並讓前端路由器接管。我懷疑這是你的應用程序發生了什麼。

在後端代碼或任何服務器配置代碼中是否有任何形式的請求重定向邏輯?

您可以做的是將您不希望前端路由接管的某些路徑列入白名單,例如以/ api開頭的路徑。在這裏粘貼你的服務器端配置將會很有幫助。

在您的服務器配置中,當inDevfalse時,您有一個app.get('*', ...),它捕獲所有請求並用靜態單頁面應用程序響應。因此API請求也會給出相同的響應。您需要重新調整路線以匹配/api之前的通配符*。可以找到一些例子here

+0

謝謝@YangShun,聽起來像是一個很好的解決方案。上面添加了我的server.js。我以前沒有將前端路線列入白名單,但會查看它。瞭解解釋過程的任何好資源? – gJanssen

+1

@gJanssen這確實是您的服務器端配置。用這個新知識更新了我的答案。 –

+1

感謝您指引我正確的方向。實際上,當inDev爲false時,只需將app.get()中的「*」更改爲「/」即可獲得我需要的結果。 – gJanssen