0

I have a small front-end and back-end separated project with development environment and production environment, so I want to set the proxy to call api. vue/cli version is 4.6.5.

file structs:

src
 axios
  api.js
  request.js
 components
  home
   LastBlogs.vue
.env.development
.env.production
package.json
vue.config.js

.env.development:

    NODE_ENV = 'development'
    
    VUE_APP_BASE_API = '/dev-api'
    
    VUE_APP_API_ADDRESS= 'http://localhost:8080/blog/'

.env.production:

    NODE_ENV = 'production'
    
    # base api
    VUE_APP_BASE_API = '/api'
    
    # api publicPath
    VUE_APP_API_ADDRESS= 'http://localhost:8080/blog'

vue.config.js:

    'use strict'
    var path = require('path')
    module.exports = {
        configureWebpack: {
            devtool: 'source-map'
        },
        assetsDir: 'static',
        devServer: {
            contentBase: path.join(__dirname, 'dist'),
            compress: true,
            port: 8001,
            proxy: {
                [process.env.VUE_APP_BASE_API]: {
                  target: [process.env.VUE_APP_API_ADDRESS], // api地址
                  changeOrigin: true,
                  ws: true,
                  pathRewrite: {
                    ['^' + process.env.VUE_APP_BASE_API]: '/api',
                  }
                }
              }
        }
    }

axios:

    import axios from 'axios'
    import qs from 'qs'
    // import {app} from '../main.js'
    
    console.log(process.env)
    
     /****** 创建axios实例 ******/
    const request = axios.create({
        baseURL: process.env.VUE_APP_API_ADDRESS,
        timeout:5000
    })
    
    // some code of interceptors
    export default request;

api.js:

    import request from './request.js'
    
    var api = process.env.VUE_APP_BASE_API //'/api'
    export function getLastBlogs(){
        return request({
            url: api+'/blog/lastBlogs',
            method: 'get'
        })
    }

I call api in vue file as this:

    <script>
    import {getLastBlogs} from '@/axios/blogApi.js'
    export default {
        name: 'LastBlogs',
        data() {
            return {
                blogs: ["AAAA", "BBBB"]
            }
        },
        created: async function(){
                
            let res = await getLastBlogs();
            this.blogs = res.data
            }
    }
    </script>

I got 404 at terminal: 404 error: xhr.js:160 GET http://localhost:8080/blog/dev-api/blog/lastBlogs 404

and the api of back end is ok: ok When I put http://localhost:8080/blog/api/blog/lastBlogs in browser, I get this: {"code":"0","msg":"操作成功","data":[{"id":1,"blogUser":1,"blogTitle":"test1","blogDescription":"for test","blogContent":"ABABABABAB","blogCreated":"2020-09-20T10:44:01","blogStatus":0},{"id":2,"blogUser":1,"blogTitle":"test2","blogDescription":"for test","blogContent":"BABABABABA","blogCreated":"2020-08-20T10:44:01","blogStatus":0}]}

What should I do? Thanks.

Qingfeng
  • 15
  • 1
  • 5

1 Answers1

0

So you are configuring Vue CLI dev-server (running on port 8001) to proxy all requests to /api to http://localhost:8080/blog/api (server) but at the same time configure Axios to use baseURL: process.env.VUE_APP_API_ADDRESS ...which means Axios is sending all requests directly to your server instead of proxy...

Just remove that baseURL: process.env.VUE_APP_API_ADDRESS from Axios config

I also believe your pathRewrite option in proxy config is incorrect.

  1. You dispatch request to /dev-api/blog/lastBlogs
  2. Request goes to Vue dev-server (localhost:8001)
  3. Proxy translates /dev-api into http://localhost:8080/blog/dev-api = http://localhost:8080/blog/dev-api/blog/lastBlogs
  4. pathRewrite is applied to whole path part of the URL - /blog/dev-api/blog/lastBlogs - RegEx ^/dev-api will not match

Try to change pathRewrite into [process.env.VUE_APP_BASE_API]: '/api'

Michal Levý
  • 33,064
  • 4
  • 68
  • 86
  • Firstly, thank you. I've tried it. remove the `baseURL: process.env.VUE_APP_API_ADDRESS`, the url turns out:http://localhost:8001/dev-api/blog/lastBlogs, and this also is 404. '/dev-api/...' still does not change to '/api/...'. – Qingfeng Oct 08 '20 at 08:49
  • `localhost:8001/dev-api/blog/lastBlogs` is correct URL you should see in the browser (Vue app -> proxy). You should check the request from dev-server to your real server (transalated one) – Michal Levý Oct 08 '20 at 09:06
  • Appreciate your patience. yeah, `localhost:8001/dev-api/blog/lastBlogs` is correct URL for axios, and port 8001 can verify the devServer of vue.config.js is working, however, the domain and URL path does not change. The option of devServer.proxy, should change the domain to `target` and change `/dev-api/...` to `/api/...`, right? I want to change `localhost:8081/dev-api/blog/lastBlogs` of axios to `localhost:8080/blog/api/blog/lastBlogs`, the interface of back end api. – Qingfeng Oct 09 '20 at 01:29
  • Thanks, I've find the reason. It does not work because the proxy config in vue.config.js is wrong. I just change `target: [process.env.VUE_APP_API_ADDRESS]` to `arget: 'http://localhost:8080/blog'` and it works. When `target: [process.env.VUE_APP_API_ADDRESS]`, the actual target of proxy is `['http://localhost:8080/blog']` which can not be deal with by http-proxy-middleware. – Qingfeng Oct 09 '20 at 03:40
  • Well that one I missed too. You can still use ENV variable, just remove square brackets... – Michal Levý Oct 09 '20 at 03:58