成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

對(duì)服務(wù)端渲染的一次實(shí)踐(帶你掌握服務(wù)端渲染)

v1 / 1640人閱讀

摘要:之前做的一個(gè)應(yīng)用,最近把首頁(yè)改成了服務(wù)端渲染的形式,過程還是很周折的,踩到了不少坑,記錄一些重點(diǎn),希望有所幫助前端使用的技術(shù)棧升級(jí)到升級(jí)到服務(wù)項(xiàng)目地址喜歡的給個(gè),感謝。。。。。。。

之前react做的一個(gè)應(yīng)用,最近把首頁(yè)改成了服務(wù)端渲染的形式,過程還是很周折的,踩到了不少坑,記錄一些重點(diǎn),希望有所幫助
前端使用的技術(shù)棧

react、react-dom 升級(jí)到 v16

react-router-dom v4

redux red-sage

antd-mobile 升級(jí)到 v2

ssr服務(wù) express

項(xiàng)目地址,喜歡的給個(gè)star,感謝。。。。。。。

訪問地址(手機(jī)模式) 非服務(wù)端渲染 服務(wù)端渲染 效果對(duì)比

前后處理流程對(duì)比

react下ssr的實(shí)現(xiàn)方式

React下同構(gòu)的解決方案有next.js、react-server等,這里,因?yàn)檫@個(gè)項(xiàng)目之前已經(jīng)采用create-react-app、redux做完了,只是想在現(xiàn)有系統(tǒng)基礎(chǔ)上把首頁(yè)改成服務(wù)端直出的方式,就選擇了webpack-isomorphic-tools這個(gè)模塊

webpack-isomorphic-tools介紹

如果我們想在現(xiàn)有React系統(tǒng)中引入同構(gòu),首先要解決的一個(gè)重要問題是:代碼中我們import了圖片,svg,css等非js資源,在客戶端webpack的各種loader幫我們處理了這些資源,在node環(huán)境中單純的依靠babel-regisiter是不行的,執(zhí)行renderToString()會(huì)報(bào)錯(cuò),非js資源沒法處理

而webpack-isomorphic-tools就幫助我們處理了這些非js資源,在客戶端webpack構(gòu)建過程中,webpack-isomorphic-tools作為一個(gè)插件,生成了一份json文件,形如:

有了這份映射文件,在同構(gòu)的服務(wù)端,renderToString()執(zhí)行的過程中,就可以正確的處理那些非js資源

比如我們有一個(gè)組件:

const App =()=>{
    return ),就生成正確的


        
    )
 //得到填滿數(shù)據(jù)的標(biāo)簽  

拼接html

注意,上面說的webpack-isomorphic-tools中生成的json文件中有js,css的對(duì)應(yīng)關(guān)系,這里我訪問那個(gè)json文件得到j(luò)s、css的路徑,拼到html中

還要返回store中保存的狀態(tài),供客戶端js createStore使用

在客戶端js中

const sagaMiddleware = createSagaMiddleware()
const store = createStore(
    reducer,
    window.__INITIAL_STATE__,
    applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(rootSaga)
路由

在做同構(gòu)的時(shí)候不能用BrowserRouter,要使用無狀態(tài)的StaticRouter,并結(jié)合location和context兩個(gè)屬性

有這樣的路由結(jié)構(gòu)

}>
//默認(rèn)跳到/home,其他的該到哪到哪

server端的代碼要這樣

const context = {}
const html = renderToString(
    
        
            
        
    )
//中訪問/,重定向到/home路由時(shí)
if (context.url) {
    res.redirect("/home")
    return
}

StaticRouter可以根據(jù)request來的url來指定渲染哪個(gè)組件,context.url指定重定向到的那個(gè)路由

也就是說,要是訪問 /,StaticRouter會(huì)給我們重定向到/home,并且StaticRouter自動(dòng)給context對(duì)象加了url,context.url就是重定向的/home,當(dāng)不是重定向時(shí),context.url是undefined

我們還可以自己寫邏輯 通過context來處理302、404等。但這里我不需要。。。。。,為什么呢?

我沒做全棧的同構(gòu),只服務(wù)端渲染了主頁(yè),渲染一個(gè)和多個(gè)差不多,全都渲染的話就是在服務(wù)端要根據(jù)當(dāng)前請(qǐng)求的路由來決定要發(fā)那些請(qǐng)求來填充Store

我對(duì)路由的處理流程上面的思維導(dǎo)圖有說明,就是在nginx中多配一個(gè)代理。

對(duì)于訪問/、/home這兩個(gè)路由,代理到ssr服務(wù),來吐首頁(yè)內(nèi)容,api代理到后端服務(wù),其他的直接返回(也就是說如果在detail頁(yè)面或user頁(yè)面刷新了頁(yè)面還是之前客戶端渲染那套)

對(duì)登錄操作的處理

上面說server端初始化數(shù)據(jù)的時(shí)候還有一個(gè)登陸問題沒說。

用戶初始訪問了服務(wù)端渲染的首頁(yè),然后在客戶端轉(zhuǎn)到登錄頁(yè)面登陸了,重新回到首頁(yè)刷新了頁(yè)面,喔,又去請(qǐng)求了ssr服務(wù),但服務(wù)端不知道當(dāng)前用戶登錄了啊,還是原來的流程,返回的__INITIAL_STATE__中還是沒有用戶的個(gè)人信息和已登錄狀態(tài)

所以,在客戶端登陸后,要將用戶的token存到cookie中,這樣,在首頁(yè)就算用戶刷新了頁(yè)面,重新請(qǐng)求頁(yè)面請(qǐng)求中也會(huì)帶上cookie,在服務(wù)端,根據(jù)request.cookies中是否有token來決定發(fā)哪些請(qǐng)求填充store

if (auth) {
    //要是有token就去查用戶信息和是否登錄狀態(tài)(還查是否登錄是因?yàn)閠oken有可能是被篡改過的)
        promises = [
            getMoviesList(store, auth),
            getCategory(store),
            checkLogin(store, auth),
            getUinfo(store, auth)
        ]
    } else {
        promises = [
            getMoviesList(store),
            getCategory(store),
        ]
}
Promise.all(promises).then(x=>{
    renderToString()
})
避免客戶端js中初始請(qǐng)求的觸發(fā)

到這一步,訪問域名,就能夠正確展示服務(wù)端渲染的頁(yè)面,跳到別的路由,客戶端的js也能正常處理接下來的事,但是,服務(wù)端渲染頁(yè)面展示后,首頁(yè)那幾個(gè)ajax請(qǐng)求還是觸發(fā)了,這是沒必要的。

原以為這是react renderToString()生成的標(biāo)簽和客戶端js hydrate()的有差異導(dǎo)致的,然而,實(shí)際上,js執(zhí)行了,組件的生命周期該觸發(fā)還是會(huì)觸發(fā)的,不只是 attach event listeners to the existing markup

所以要手動(dòng)避免

在App組件中

componentDidMount() {
        if (!window.__INITIAL_STATE__) {
            this.props.checkLogin()
            this.props.loadCategory()
        }
    }

//當(dāng)當(dāng)前頁(yè)面是服務(wù)端返回的(因?yàn)閣indow.__INITIAL_STATE__有初始狀態(tài)),初始的ajax就不觸發(fā)了
總結(jié)

服務(wù)端渲染的坑還是挺多的,這一個(gè)星期就搞它了。。。。這里記錄一些比較重要的東西,具體細(xì)節(jié)有興趣的可以看下代碼.最后,最重要的,喜歡的給個(gè)star,感謝。。。。。。。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92464.html

相關(guān)文章

  • 細(xì)說 Vue 組件的服務(wù)渲染

    摘要:所以,這次就來聊聊組件的服務(wù)器端渲染。這種模式下,后端只提供接口,傳統(tǒng)的服務(wù)器端路由模板渲染則都有層接管。這樣,前端開發(fā)人員可以自由的決定哪些組件需要在服務(wù)器端渲染,哪些組件可以放在客戶端渲染,前后端完全解耦,但又保留了服務(wù)器端渲染的功能。 細(xì)說 Vue 組件的服務(wù)器端渲染 聲明:需要讀者對(duì) NodeJs、Vue 服務(wù)器端渲染有一定的了解 現(xiàn)在,前后端分離與客戶端渲染已經(jīng)成為前端開發(fā)的...

    reclay 評(píng)論0 收藏0
  • 開發(fā)知識(shí)點(diǎn)整理

    摘要:前言本文主要是有關(guān)前端方面知識(shí)按照目前的認(rèn)知進(jìn)行的收集歸類概括和整理,涵蓋前端理論與前端實(shí)踐兩方面。 前言:本文主要是有關(guān)前端方面知識(shí)按照 XX 目前的認(rèn)知進(jìn)行的收集、歸類、概括和整理,涵蓋『前端理論』與『前端實(shí)踐』兩方面。本文會(huì)告訴你前端需要了解的知識(shí)大致有什么,看上去有很多,但具體你要學(xué)什么,還是要 follow your heart & follow your BOSS。 初衷...

    Blackjun 評(píng)論0 收藏0
  • 開發(fā)知識(shí)點(diǎn)整理

    摘要:前言本文主要是有關(guān)前端方面知識(shí)按照目前的認(rèn)知進(jìn)行的收集歸類概括和整理,涵蓋前端理論與前端實(shí)踐兩方面。 前言:本文主要是有關(guān)前端方面知識(shí)按照 XX 目前的認(rèn)知進(jìn)行的收集、歸類、概括和整理,涵蓋『前端理論』與『前端實(shí)踐』兩方面。本文會(huì)告訴你前端需要了解的知識(shí)大致有什么,看上去有很多,但具體你要學(xué)什么,還是要 follow your heart & follow your BOSS。 初衷...

    Sike 評(píng)論0 收藏0
  • 開發(fā)知識(shí)點(diǎn)整理

    摘要:前言本文主要是有關(guān)前端方面知識(shí)按照目前的認(rèn)知進(jìn)行的收集歸類概括和整理,涵蓋前端理論與前端實(shí)踐兩方面。 前言:本文主要是有關(guān)前端方面知識(shí)按照 XX 目前的認(rèn)知進(jìn)行的收集、歸類、概括和整理,涵蓋『前端理論』與『前端實(shí)踐』兩方面。本文會(huì)告訴你前端需要了解的知識(shí)大致有什么,看上去有很多,但具體你要學(xué)什么,還是要 follow your heart & follow your BOSS。 初衷...

    tracy 評(píng)論0 收藏0
  • 淺談前后分離與實(shí)踐 之 nodejs 中間層服務(wù)(二)

    摘要:服務(wù)端任需要進(jìn)行校驗(yàn)來達(dá)到數(shù)據(jù)的可靠性前端的路由可能在服務(wù)端并不存在等等這一系列重用性的問題。串行并行,大幅縮短請(qǐng)求時(shí)間。關(guān)于作者本人主頁(yè)本文部分圖片段落參考文章淘寶前后端分離實(shí)踐微信公眾號(hào)會(huì)不定期推送前端技術(shù)文章,歡迎關(guān)注 一、背景 書接上文,淺談前后端分離與實(shí)踐(一) 我們用mock服務(wù)器搭建起來了自己的前端數(shù)據(jù)模擬服務(wù),前后端開發(fā)過程中只需定義好接口規(guī)范,便可以相互進(jìn)行各自的開發(fā)...

    ddongjian0000 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<