react-ssr之node代理

src/server/index.js 中配置代理

主要借用 httpProxy 插件實現

const Koa = require('koa2')
const _ = require('koa-route');
const httpProxy = require('http-proxy-middleware');
import render from './render'
const k2c = require('koa2-connect');
const port = 4000
let app = new Koa()

// 代理插件配置
app.use(async (ctx, next) => {
    if (ctx.url.startsWith('/api')) {
        await k2c(httpProxy({
        target: 'http://127.0.0.1:4001', 
        changeOrigin: true,
        secure: false,
        }
        ))(ctx,next);
    }
    await next()
});

// 設置服務端靜態目錄
app.use(require('koa-static')('public'))
// 這裏路徑改爲*, 不管哪個路徑,都組走這裏
app.use(_.get('*', render))

app.listen(port, () => {
    console.log(`server start at ${port}`)
})

配置axios basepath

配置好以後我們就不用再添加host了,走默認配置

  • 在src/client/下新建request.js,內容如下
import axios from 'axios'
// 創建一個axios的實例, 配置baseURL的基準路徑
export default axios.create({
  baseURL: '/'
})

src/server/request.js 新建文件

這裏是服務端的請求配置

import axios from 'axios'
// 創建一個axios的實例, 配置baseURL的基準路徑
// 服務器端訪問的時候訪問4001
export default (ctx) => axios.create({
  baseURL: 'http://localhost:4001',
  headers: {
    cookie: ctx.req.headers.cookie || '' // 從請求中拿到cookie
  }
})

src/client/request.js 新建文件

這裏是客戶端的請求配置

import axios from 'axios'
// 創建一個axios的實例, 配置baseURL的基準路徑
export default axios.create({
  baseURL: '/'
})

修改src/store/index.js, 給redux參數

使用 withExtraArgument 給think傳遞額外的參數
服務端和客戶端傳入不同的請求對象

import { createStore, applyMiddleware } from 'redux'
// import saga from 'redux-saga'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
import reducers from './reducers'
import clientRequest from '../client/request'
import serverRequest from '../server/request'

// withExtraArgument 給redux-thunk傳遞自定義參數
export function getServerStore () {
    return createStore(
        reducers,
        applyMiddleware(thunk.withExtraArgument(serverRequest), logger)
    )
}

export function getClientStore () {
    let initState = window.content.state
    return createStore(
        reducers,
        initState,
        applyMiddleware(thunk.withExtraArgument(clientRequest), logger)
    )
}

actions的修改

這裏不在使用import引入的axios請求數據,而換成我們傳遞過來的request對象

import * as types from '../action-types' 

export default {
    login ({user}) {
        return function (dispatch, getState, request) {
            return request.post('/api/login', {
                data: user
            }).then(res=>{
            let {data} = res
            dispatch({
                type: types.SET_SESSION,
                payload: data.data
            }) 
        })
        }
    },
    logout () {
        return function (dispatch, getState, request) {
            return request.get('/api/logout').then(res=>{
            let {data} = res
            dispatch({
                type: types.SET_SESSION,
                payload: data.data
            }) 
        })
        }
    },
    getUser () {
        return function (dispatch, getState, request) {
            return request.get('/api/user').then(res=>{
                let {data} = res
                dispatch({
                    type: types.SET_SESSION,
                    payload: data.data
                }) 
            })
        }
    }
}

總結

實現步驟如下:

  • 使用httpProxy進行服務器的代理配置
  • 修改服務端和客戶端的request對象,設置basePath
  • 將不同的請求對象傳遞給不同redcer
  • 再actions中使用傳遞過來的request對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章