Express:由于缺少accept:application/javascript标头,无法从浏览器访问路由。

3

我是express的新手。我有一个运行在express上的Vue应用程序。我有一些API路由,我可以通过浏览器使用axios访问。为了使用postman访问这些路由,我必须要有以下头部:

accept: application/javascript

为了让API返回实际结果,我需要使用这个头部信息。如果不使用这个头部信息,我会从webpack得到生成的index.html。我需要重复使用其中一个路由来返回基于参数的Excel/PDF,并通过页面上的链接进行访问。

这是我的server.js - 基于https://github.com/southerncross/vue-express-dev-boilerplate

import express from 'express'
import path from 'path'
import favicon from 'serve-favicon'
import logger from 'morgan'
import cookieParser from 'cookie-parser'
import bodyParser from 'body-parser'
import webpack from 'webpack'

const argon2 = require('argon2');
const passport = require('passport')
const LocalStrategy = require ('passport-local')
const session = require('express-session')


import history from 'connect-history-api-fallback'

// Formal(Prod) environment, the following two modules do not need to be introduced
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'

import config from '../../build/webpack.dev.conf'

const app = express()
app.set('trust proxy', true)

app.set("view engine", "pug")
app.set('views', path.join(__dirname, 'views'))

app.use ('/', require('./routes'))


app.use(session({
 secret: process.env.SESSION_SECRET || 'secretsauce',
 resave: false,
 saveUninitialized: true
}))


app.use(history())
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')))

const compiler = webpack(config)

app.use(webpackDevMiddleware(compiler, {
 publicPath: config.output.publicPath,
 stats: {
  colors: true
 }
}))

app.use(webpackHotMiddleware(compiler))



////////// PASSPORT ///////////////////////
app.use (passport.initialize ());
app.use (passport.session ());

async function authenticateUser (username, password) {
//...
  
}

passport.use (
 new LocalStrategy (async (username, password, done) => {
  const user = await authenticateUser (username, password)
  if (!user) {
   return done (null, false, {
    message: 'Username and password combination is wrong',
   });
  }

  delete user.password;
  return done (null, user)
 })
);

// Serialize user in session
passport.serializeUser ((user, done) => {
 done (null, user);
});

passport.deserializeUser (function(user, done) {
 if(user === undefined || !user || Object.keys(user).length === 0)
  return done(null, false)
 else
  done (null, user);
});

//////////// passport end ///////////////


app.set("view engine", "pug")
app.use(express.static(path.join(__dirname, 'views')))
app.get('/', function (req, res) {
 res.sendFile('./views/index.html')
})
app.get('/success', function (req, res) {
 res.render('./views/success')
})



app.use ('/api', require('./api'))


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

app.use(function (err, req, res) {
 res.status(err.status || 500)
 res.send(err.message)
})




let server = app.listen(80)

export default app

以下是 api.js 的一小部分代码:

const {Router} = require ('express')
const router = Router()

router.get('/whome', function(req, res){
 logger.info('whome', req.user)
 return res.json(req.user)
})


router.get ('/hello', auth.isAuthenticated, async (req, res) => {
 res.json ({text:'hello'})
})

module.exports = router

我可以在Postman中使用accept:application/javascript标头调用http://localhost/api/hello,然后得到以下结果:

{
    "text": "hello"
}

预料之中。但是如果我从浏览器调用同样的URL(且没有发送该标头),我会得到创建的捆绑索引文件index.html。如何从浏览器访问这些路由?


在您的浏览器应用程序中,您确定正在正确调用API端点吗?而且,您是在使用哈希路由还是历史路由?如果您正在使用历史路由,则我怀疑它可能与“'connect-history-api-fallback'”包有关。尝试将其删除并查看会发生什么。 - Khauri
1个回答

1
你有两个选项。
第一个选项是,在服务器上尝试添加以下内容: app.options('*', cors()) 在以下代码之前:app.set("view engine", "pug") 如果这不起作用,请尝试安装此插件到您的Google Chrome浏览器中进行测试。

Allow-Control-Allow-Origin: *

并启用它。(图标应该是绿色而不是红色)。
为什么会出现这种情况? 正在进行的请求称为预检请求。 预检请求由浏览器发出,因为CORS仅是浏览器安全限制 - 这就是为什么Postman可以工作,当然,它不是浏览器。
参考资料:Preflight request

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接