【问题标题】:XHR pre-flight with Express Node.js使用 Express Node.js 进行 XHR 预试
【发布时间】:2018-07-15 19:36:37
【问题描述】:

我正在尝试制作一个“MEVN”应用程序(MongoDB、Express、Vue、NodeJs)。

在客户端,我有一个 vue 组件,它提供了一个创建帖子的表单。帖子基本上是标题和描述。所以我有这样的事情:

methods: {
  async addPost () {
    await PostsService.addPost({
      title: this.title,
      description: this.description
    })
    this.$router.push({ name: 'Posts' })
  }
}

My PostsService 是处理帖子的助手:

import Api from '@/services/Api'

export default {
  addPost (params) {
    return Api().post('posts', params)
  },
}

我的 Api 是一个简单的 axios 构造函数:

import axios from 'axios'

export default() => {
  return axios.create({
    baseURL: `http://localhost:8081`
  })
}

在服务器端,我有一个入口点:

var express = require('express')
  , app = express()

app.use(require('./controllers'))

app.listen(8081, function() {
  console.log('Listening on port 8081...')
})  

启动控制器加载器:

var express = require('express')
  , router = express.Router()

router.use('/posts', require('./posts'))

module.exports = router

后控制器如下所示:

var express = require('express')
  , router = express.Router()
  , Post = require('../models/post')

// Add new post
router.post('/posts', function(req, res) {
  var title = req.title;
  var description = req.description;
  post = Post.create(title, description);
  if(post) {
    res.send({flag: 'SUCCESS', content: post})
  } else {
    res.send({flag: 'ERROR', content: 'Failed to create the post'})
  }
})

module.exports = router

如您所见,models/post 有一些操作将建立数据库连接并保存帖子。

当我使用 npm start 启动服务器时,我确认我正在侦听端口 8081。

当我调用 addPost() 函数时,我收到了两个 XHR 请求:

第一个 XHR

    Request URL: http://localhost:8081/posts
    Request Method: OPTIONS
    Status Code: 204 No Content
    Remote Address: [::1]:8081
    Referrer Policy: no-referrer-when-downgrade
    Access-Control-Allow-Headers: content-type
    Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
    Access-Control-Allow-Origin: *
    Connection: keep-alive
    Content-Length: 0
    Date: Sun, 15 Jul 2018 18:20:01 GMT
    Vary: Access-Control-Request-Headers
    X-Powered-By: Express
    Accept: */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en,fr-FR;q=0.9,fr;q=0.8,en-US;q=0.7,en-GB;q=0.6
    Access-Control-Request-Headers: content-type
    Access-Control-Request-Method: POST
    Connection: keep-alive
    Host: localhost:8081
    Origin: http://localhost:8080
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

第二个 XHR

    Request URL: http://localhost:8081/posts
    Request Method: POST
    Status Code: 404 Not Found
    Remote Address: [::1]:8081
    Referrer Policy: no-referrer-when-downgrade
    Access-Control-Allow-Origin: *
    Connection: keep-alive
    Content-Length: 145
    Content-Security-Policy: default-src 'self'
    Content-Type: text/html; charset=utf-8
    Date: Sun, 15 Jul 2018 18:20:01 GMT
    X-Content-Type-Options: nosniff
    X-Powered-By: Express
    Accept: application/json, text/plain, */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en,fr-FR;q=0.9,fr;q=0.8,en-US;q=0.7,en-GB;q=0.6
    Connection: keep-alive
    Content-Length: 35
    Content-Type: application/json;charset=UTF-8
    Host: localhost:8081
    Origin: http://localhost:8080
    Referer: http://localhost:8080/posts/new
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
    {title: "test", description: "test"}

第二个 XHR 失败并告诉我:无法 POST /posts

你能解释一下发生了什么以及如何解决它吗?

谢谢

【问题讨论】:

    标签: node.js express vue.js xmlhttprequest express-router


    【解决方案1】:

    您的路由处理程序适用于/posts/posts,因此您实际上并没有仅用于/posts 的路由处理程序。 /posts/posts 路径的第一部分来自这里:

    router.use('/posts', require('./posts'))
    

    添加到第一个 /posts 的第二个来自:

    router.post('/posts', function(req, res) {...}
    

    这两个是相加的,因此您拥有处理程序的 URL 是 /posts/posts

    我猜OPTIONS 请求有效,因为您安装了一些通用的 CORS 中间件,当使用 OPTIONS 请求时,它会批准所有路由。第二个请求失败,因为没有针对 /posts 的路由处理程序,只有一个针对 /posts/posts 的路由处理程序。


    你可以通过改变这个来解决这个问题:

    router.use('/posts', require('./posts'))
    

    到:

    router.use(require('./posts'))
    

    或者,通过改变这个:

    router.post('/posts', function(req, res) {..}
    

    到这里:

    router.post('/', function(req, res) {..}
    

    选择哪一个取决于您是希望后控制器路由器上的每个路由都继承 /posts 作为路径的根,还是要在后控制器路由器的顶层定义多个路由。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-30
      • 2014-09-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2012-10-26
      • 1970-01-01
      • 2012-01-20
      相关资源
      最近更新 更多