我犯了个简单错误:express做反向代理,问题排查

起因

我写了一个后台,前端想要调用我的接口,他前段写的是vue
使用chrome调用我的接口的时候,遇到了跨域请求,我查了查flask跨域,没想到挺麻烦的
正好之前写过一个简单的代理服务器,所以想先用代理服务器将就着,到时候再上nginx

问题

第一张图是运行了vue,然后直接在浏览器访问
第二张图是通过node express反向代理访问返回的错误信息

node后台有收到一个html请求

vue的html请求成功发送接收,但是所有的js都失败了
最后三个成功的css是请求到chrome的自身缓存了,所以都成功了

node 代码

const express = require('express')
const http = require('http')
const axios = require('axios')

var app = express()

const python_remote = "127.0.0.1"
const python_port = 8000

const vue_remote = '127.0.0.1'
const vue_port = 8080

const running_port = 3000

function transport(hostname, port, slice_num=0){
    return (req, res) => {
        console.log(req.originalUrl)
        const option = {
            hostname: hostname,
            port: port,
            path: req.originalUrl.slice(slice_num),
            method: req.method,
            headers: req.headers,
        }
        const request = http.request(option, async function(response){
            res.statusCode = response.statusCode
            for(key in response.headers){
                res.header(key, response.headers[key])
            }
            response.pipe(res)
        })
        request.on('error', function(error){
            console.log(error)
        })
        req.pipe(request)
    }
}

app.all('/vue', transport(vue_remote, vue_port, 4))

app.all('/js', transport(vue_remote, vue_port))

app.all('/python', transport(python_remote, python_port))


app.listen(running_port, function(){
    console.log(`Server running on port ${running_port}`)
})

transport 函数的第三个参数是用来将多余的路径去除的
例如原本vue的请求是发送到了/#/xxxx
那么为了不和后台的python起冲突,所以加了/vue,变成了/vue/#/xxx
但是传给vue服务的时候,还是得变回原样,所以弄了个小东西,将额外加的去除

疑惑

为了测试请求都到哪里去了,我改了一下代码

function transport(flag, hostname, port, slice_num=0){
    return (req, res) => {
        console.log(flag, req.originalUrl)
        ......
}
app.all('/vue', transport('vue', vue_remote, vue_port, 4))

app.all('/js', transport('vue js', vue_remote, vue_port))

app.all('/python', transport('python', python_remote, python_port))

然而改了之后,并没有见到接收到请求
只收到了vue的请求

这个时候,我有了两个猜测

1、我的js请求的路径有错误
2、只有js是错误的,那么是不是js被express当做了不一样的东西,走了别的路径

猜测1错误,访问地址的确是

猜测2,可能是js被当成了静态文件,所以去查查express如何对待静态文件的
然而并不是,express需要指定添加静态文件的操作方法

要不先*一下,看看有没有收到请求吧

*号表示接受所有的请求,下面这句是在原来基础上额外添加
在所有请求都不匹配的情况下,会走*好路径

app.all('*', transport('star', vue_remote, vue_port))

然后很神奇的收到了请求,可是为什么呢?

                                             黑人問號| 香港網絡大典| Fandom

啊~
人生啊~

那既然*号是可以的,那我再/js后面打上*好可不可以呢

app.get('/js*', transport('vue js', vue_remote, vue_port))

结果非常的Amazing

 虽然还少了Vue的标志性照片
但是问题已经被解决了
原来express用的不是前缀匹配而是全匹配

前缀匹配应用的场景是使用了express Router的时候

解决办法:在前缀后面加上*号

node代码

const express = require('express')
const http = require('http')

var app = express()

const python_remote = "127.0.0.1"
const python_port = 8000

const vue_remote = '127.0.0.1'
const vue_port = 8080

const running_port = 3000

function transport(hostname, port, slice_num=0){
    return (req, res) => {
        const option = {
            hostname: hostname,
            port: port,
            path: req.originalUrl.slice(slice_num),
            method: req.method,
            headers: req.headers,
        }
        const request = http.request(option, async function(response){
            res.statusCode = response.statusCode
            for(key in response.headers){
                res.header(key, response.headers[key])
            }
            response.pipe(res)
        })
        request.on('error', function(error){
            console.log(error)
        })
        req.pipe(request)
    }
}

app.all('/vue*', transport(vue_remote, vue_port, 4))
app.get('/js*', transport(vue_remote, vue_port))
app.get('/img*', transport(vue_remote, vue_port))

app.all('/python*', transport(python_remote, python_port, 7))

app.listen(running_port, function(){
    console.log(`Server running on port ${running_port}`)
})

 

vue返回结果

经测试,flask也能够正常访问

猜你喜欢

转载自blog.csdn.net/Gragon_Shao/article/details/112907362