React Typescript音乐播放器项目笔记:5、create-react-app搭建代理(二)

19 篇文章 0 订阅
17 篇文章 0 订阅

项目地址https://github.com/BUPTlhuanyu/react-music-lhy

create-react-app搭建代理(二)

create-react-app搭建代理(一)介绍了如何通过devServer.before自定义路由从而搭建代理,本文给出另外一种方法。经过npm run eject之后配置代理,create-react-app用的是webpack-dev-server实现一个简单的web服务器,webpack-dev-server是基于express实现的。webpack-dev-server相关配置可参考webpack中devServer

利用express搭建一个本地服务器

在script文件夹下创建一个server.js文件搭建服务器,代码如下:

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

const app = express()

const apiRoutes = express.Router()
apiRoutes.get('/getDiscList', function (req, res) {
    var url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
    axios.get(url, {
        headers: {
            referer: 'https://c.y.qq.com/',
            host: 'c.y.qq.com'
        },
        params: req.query
    }).then((response) => {
        res.json(response.data)
    }).catch((e) => {
        console.log(e)
    })
})
app.use('/api', apiRoutes)


const server = app.listen(3111,function() {
    console.log("Server running on port %s", server.address().port);
})

package.json设置proxy为本地服务器监听的端口

在package.json文件中添加如下代码:

"proxy": "http://localhost:3111"

目的是,当设置proxy的时候,根据create-react-app中start.js以及webpackDevServer.config.js来设置devServer.proxy
start.js中相关代码如下

// Load proxy config
  //没有配置packjson的时候proxyConfig为undefined
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
// Serve webpack assets generated by the compiler over a web server.
  //urls.lanUrlForConfig是根据协议,host以及端口生成的,这里为本机的ip地址
const serverConfig = createDevServerConfig(
  proxyConfig,
  urls.lanUrlForConfig
);
//利用webpack-dev-server插件根据webpack生成的编译器以及自定义的服务器配置来生成devServer
const devServer = new WebpackDevServer(compiler, serverConfig);

首先拿到packjson中的proxy的值,然后通过prepareProxy函数获取一个proxyConfig对象,prepareProxy函数相关代码如下,由于package.json中proxy为字符串形式(proxy其实不允许是对象,prepareProxy函数部分代码有问题),所以只需要看处理字符串的相关代码。

  // Support proxy as a string for those who are using the simple proxy option
  if (typeof proxy === 'string') {
    if (!/^http(s)?:\/\//.test(proxy)) {
      console.log(
        chalk.red(
          'When "proxy" is specified in package.json it must start with either http:// or https://'
        )
      );
      process.exit(1);
    }

    let target;
    if (process.platform === 'win32') {
      target = resolveLoopback(proxy);
    } else {
      target = proxy;
    }
    return [
      {
        target,
        logLevel: 'silent',
        context: function(pathname, req) {
          return (
            req.method !== 'GET' ||
            (mayProxy(pathname) &&
              req.headers.accept &&
              req.headers.accept.indexOf('text/html') === -1)
          );
        },
        onProxyReq: proxyReq => {
          if (proxyReq.getHeader('origin')) {
            proxyReq.setHeader('origin', target);
          }
        },
        onError: onProxyError(target),
        secure: false,
        changeOrigin: true,
        ws: true,
        xfwd: true,
      },
    ];
  }

最终proxyConfig将会是一个数组:
[
{
target:“http://localhost:3111”,
logLevel: ‘silent’,

secure: false,
changeOrigin: true,
ws: true,
xfwd: true,
},
]
然后通过webpackDevServer.config.js中export的方法,将proxyConfig作为该函数参数赋值给返回对象的proxy:

{
	proxy:[
      {
        target:"http://localhost:3111",
        logLevel: 'silent',
		...
        secure: false,
        changeOrigin: true,
        ws: true,
        xfwd: true,
      },
    ]
}

该对象即为serverConfig,然后在start.js中执行如下代码,利用webpack-dev-server插件根据webpack生成的编译器以及自定义的服务器配置来生成devServer,因此webpac-dev-servr可以代理port(默认为3000端口)的所有请求。由于serverConfig中的端口为3111,此时只需要搭建一个服务器来监听3111端口即可,在3000端口的请求上如果没有匹配到webpack-dev-server服务器上的路由,那么webpack-dev-server服务器会将来自3000端口的请求代理到3111端口的服务器上。

devServer = new WebpackDevServer(compiler, serverConfig);
devServer.listen(port, HOST,errFunc)

package.json设置同时启动webpac-dev-server服务器与本地服务器

首先需要安装concurrently依赖用于同时运行两个npm命令

npm install --save-dev concurrently

然后在package.json中修改scripts,如下所示:

  "scripts": {
    "dev": "node scripts/start.js",
    "server": "node scripts/server.js &",
    "start": "concurrently \"npm run server\" \"npm run dev\" ",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js"
  }

运行 npm start 即可,结果如下:

webpac-dev-server服务器匹配到请求就不会将请求转发到本地服务器

将上面操作保留,并增加create-react-app搭建代理(一)中所作的操作:
在start.js中修改为如下代码:

//增加的代码
const appRoute = require('../server/server.js')
//在before中增加代码
module.exports = function(proxy, allowedHost) {
	return {
		...
		//增加的代码
		before(app, server) {
			...
			appRoute(app)
			...
		}
	}
}

server/server.js下的代码修改为,返回"NO":

apiRoutes.get('/getDiscList', function (req, res) {
    var url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
    axios.get(url, {
        headers: {
            referer: 'https://c.y.qq.com/',
            host: 'c.y.qq.com'
        },
        params: req.query
    }).then((response) => {
        res.json("no")
    }).catch((e) => {
        console.log(e)
    })
})

npm start得到如下结果

总结

向http://localhost:3000的请求被webpack-dev-server服务器代理——>如果没有路由就将代理转发到本地服务器,本地服务器从远端获取到数据之后将数据返回给webpack-dev-server服务器最后返回给http://localhost:3000上的客户端。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值