All Projects → VerdantSparks → Vuejs Aspnetcore Ssr

VerdantSparks / Vuejs Aspnetcore Ssr

Licence: mit
🆙 VueJS 2.5 Server Side Rendering on ASP.NET Core 2 and more

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Vuejs Aspnetcore Ssr

Vuejsssrsample
ASP.NET Core Vue.js server-side rendering sample:
Stars: ✭ 146 (+156.14%)
Mutual labels:  vuex, vuejs2, server-side-rendering
Easy Vue
Learn vueJS Easily 👻
Stars: ✭ 896 (+1471.93%)
Mutual labels:  vuex, vuejs2
Vuejs Snippets
Collection of Vuejs 2.0+ snippets
Stars: ✭ 17 (-70.18%)
Mutual labels:  vuex, vuejs2
Blog Admin
personal blog administration and management, by iview
Stars: ✭ 13 (-77.19%)
Mutual labels:  vuex, vuejs2
Vue Ts Daily
基于vue、Typescript、pwa的一款习惯养成app
Stars: ✭ 735 (+1189.47%)
Mutual labels:  vuex, vuejs2
Vue Chat
👥Vue全家桶+Socket.io+Express/Koa2打造一个智能聊天室。
Stars: ✭ 887 (+1456.14%)
Mutual labels:  vuex, vuejs2
Vue Entity Adapter
Package to maintain entities in Vuex.
Stars: ✭ 20 (-64.91%)
Mutual labels:  vuex, vuejs2
Vue Crud
Vue.js based REST-ful CRUD system
Stars: ✭ 629 (+1003.51%)
Mutual labels:  vuex, vuejs2
Vuejs Interview Questions
List of 300 VueJS Interview Questions And Answers
Stars: ✭ 948 (+1563.16%)
Mutual labels:  vuex, vuejs2
Createmap
Create a Map - City of Baltimore
Stars: ✭ 31 (-45.61%)
Mutual labels:  vuex, vuejs2
Vuetify Material Dashboard
Vuetify Material Dashboard - Open Source Material Design Admin
Stars: ✭ 1,023 (+1694.74%)
Mutual labels:  vuex, vuejs2
Vue Music Player
🎵Vue.js写一个音乐播放器+📖One(一个).A music player + One by Vue.js
Stars: ✭ 729 (+1178.95%)
Mutual labels:  vuex, vuejs2
Vuex I18n
Localization plugin for vue.js 2.0 using vuex as store
Stars: ✭ 657 (+1052.63%)
Mutual labels:  vuex, vuejs2
Vue Meteor
🌠 Vue first-class integration in Meteor
Stars: ✭ 893 (+1466.67%)
Mutual labels:  vuex, vuejs2
Cordova Template Framework7 Vue Webpack
Framework7 - Vue - Webpack Cordova Template with Webpack Dev Server and Hot Module Replacement
Stars: ✭ 630 (+1005.26%)
Mutual labels:  vuex, vuejs2
Manhuaren
vue2.0全家桶,仿漫画人官网(移动端)
Stars: ✭ 18 (-68.42%)
Mutual labels:  vuex, vuejs2
Vue Pomo
A progressive web app for the Pomodoro Technique, built with Vue 2.0, Vuex and Firebase.
Stars: ✭ 51 (-10.53%)
Mutual labels:  vuex, vuejs2
Vuex Shared Mutations
Share vuex mutations between tabs/windows
Stars: ✭ 532 (+833.33%)
Mutual labels:  vuex, vuejs2
Vue Typescript Dpapp Demo
🔥 Let's start with TypeScript
Stars: ✭ 613 (+975.44%)
Mutual labels:  vuex, vuejs2
Vms
A Vue.js 2.0 Content Management System
Stars: ✭ 885 (+1452.63%)
Mutual labels:  vuex, vuejs2

README

This repository was built from scratch following the steps described in the original blog post Server rendering Vue.js applications with ASP.NET Core from Stu Ratcliffe. The aim of this repository is to adding more steps and comments from my experience following the steps that make it works as a supplement of the original blog post. I personally did not have any prior knowledge in VueJS nor modern web development frameworks. I were a C# developer and learn VueJS by my own from VueJS documentation and Stu Ratcliffe blog post. Hope this helps if you also read the same blog post and got stuck some way. 🙏 😀

You can get the complete code repo made by Stu Ratcliffe from [Here]

Once you get used to this repository, you may want to know how to do the same thing in Typescript. @Kukks has forked this repository and use Typescript instead. You can find his repository [Here]

Install and run:

dotnet restore
npm install
dotnet run

if you see the following lines, than you are looking great!

Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.NodeServices[0]
    webpack built c91dc3e2f186f013c53c in 3212ms

Packages used: The description may not accurate, just my understanding

  • vue <- VueJS

  • lodash <- similiar to numpy in Python, utilies library for manipulating array/object.

  • axios <- Promise based HTTP client for the browser and Node.js, think of $.ajax() if you come from jQuery world

  • vuex <- Vue variant of Flux implementation, just like Redux in React

  • nprogress <- loading indiciator

  • vue-router <- enable client side "page" routing

  • vue-server-renderer <- enable Server Side Rendering

  • aspnet-prerendering <- enable ASP.NET to trigger Node for SSR

  • webpack <- pack your JavaScript files into bundles for faster loading, remove duplicate imports, reduce final code size

  • webpack-cli <- since webpack version 4 the command line tool placed in this package instead, install only if you want to pack the JavaScript code manually

  • webpack-merge <- merge webpack config so common configuration attributes can be shared among configurations

  • webpack-hot-middleware <- enable hot reload of code changes

  • aspnet-webpack <- enable ASP.NET to execute webpack on demand during runtime.

  • vue-loader <- required for packing vuejs code

  • css-loader <- required if you have css file to pack

  • style-loader <- required if you use template with style

  • json-loader <- requiredd if you need to pack json file

  • vue-template-compiler <- required for packing if you use template in vue components

  • babel-* <- transpile code syntax used in Vue into browser understandable version before packing

Working with data:

  • .Net part
    1. Message.cs
    2. FakeMessageStore.cs
    3. ClientState.cs
  • Vue part 0. (create ClientApp/vuex folder)
    1. ClientApp/vuex/action.js
    2. ClientApp/vuex/store.js

Client side routing:

  1. Move to ClientApp/components
  2. Dashboard.vue
  3. Messages.vue
  4. Modify App.vue
  5. create ClientApp/router folder
  6. Move to ClientApp/router
  7. index.js
  8. Move back to ClientApp folder
  9. Modify app.js
  10. Move back to .
  11. Modify Startup.cs

Loading indicator:

Here we try to modify the implementation order different from the original post. We are going to add the loading indicator before implementing the Server Side Rendering. To simulate timely API call form remote server, we add the following line in HomeController.cs:

public JsonResult initialMessages(){
    //Added to simulate initial loading from remote server
    Thread.Sleep(2000);
    ...
}
  1. Add nprogess in package.json dependency:

     "dependencies": {
         "vue": "^2.5.8",
         "vuex": "^3.0.1",
         "vue-router": "^3.0.1",
         "lodash": "^4.17.4",
         "axios": "^0.17.1",
         "nprogress": "^0.2.0"
     }
    
  2. Add style-loader and css-loader to webpack.config:

     { 
         test: /\.css$/, 
         loader: "style-loader!css-loader" 
     }
    
  3. Modify ClientApp/vuex/actions.js, add NProgress.start() and NProgress.done() before and after axios remote call.

Server Side Renderering (SSR)

  1. Add the following dependencies to package.json:

    • devDependencies:
      • aspnet-webpack
      • webpack-merge
    • dependencies:x
      • vue-server-renderer
      • aspnet-prerenderer
  2. Split the code into two part:

    1. server.js <- this will load by renderOnServer.js, which aspnet-prerendering will trigger Node to execute and return pre-rendered result back to renderOnServer.js and thus send to browser as initial state of app.
    2. client.js <- once initial app state rendered and injected in the resulting index.cshtml, the script tag will load client.js and mount it to pre-rendered app tag.
  3. Create Node server code for ASP.NET Core to trigger the Node hosting service to execute

    • rendererOnServer.js <- responsible for loading the webpacked server.js for Node to render the initial app state.
  4. ASP.NET Core part

    • Edit Views/Home/index.cshtml app tag to use aspnet-prerendering attributes
  5. Webpack Configuration

    • Edit webpack.config.js, make use of webpack-merge to split the original configuration into two sets.

Thoughts:

SSR was by far the most difficult part of my VueJS journey, it takes more than half of the time of my VueJS learning. Whether to use Server Side Rendering or not is highly optional, you don't need it to write a cool SPA. The performance and user experience gain is arguablely worth the complexity and develop time involved.

BootstrapVue:

Bootstrap is a very popular library for beautiful and simple UI components and styles. Using Bootstrap in VueJS application is easy with BootstrapVue (it seems bootstrap is not required in package.json to use bootstrap-vue, installing bootstrap-vue install bootstrap as well):

  • Install: npm i bootstrap-vue
  • Import into app.js: `import BootstrapVue from 'bootstrap-vue'
  • Import the css files: (tricky here, for this repo I need to add the imports at client.js instead of app.js)
    import 'bootstrap/dist/css/bootstrap.css' import 'boostrap-vue/dist/bootstrap-vue.css'
  • Add the Bootstrap components (e.g. I added a badge at Dashboard.vue template.)

Prevent XSS Attack:

During the journey in solving the asp-prerendering v3.0.0+ dependency issue, I found an article talking about Cross-site scripting attack in JavaScript applications: The Most Common XSS Vulnerability in React.js Applications And turns out rednerOnServer.js also has such vulnerability.

module.exports = prerendering.createServerRenderer(function (params) {
return new Promise(
    function (resolve, reject) {
    const context = {
        url: params.url,
        xss:"</script><script>alert('Possible XSS vulnerability from user input!')</script>"
    }
    resolve({
        globals: {
        __INITIAL_STATE__: context
        }
    })
})
});

If we modify the renderOnServer.js as above, an alert will be shown when we load the page from browser. This will potentially enable attacker to execute arbitary code. To fix this vulnerability, we can make use of serialize-javascript package from Yahoo engineers and cleanse all initial state assignment from user input:

npm install --save serialize-javascript

and serialize the initial state like this:

//prevent XSS attack when initialize state
var serialize = require('serialize-javascript')

module.exports = prerendering.createServerRenderer(function (params) {
    return new Promise(
        function (resolve, reject) {
            const context = {
            url: params.url,
            xss: serialize("</script><script>alert('Possible XSS vulnerability from user input!')</script>")
        }
        resolve({
            globals: {
            __INITIAL_STATE__: context
            }
        })
    })
});

and when you inspect the HTML from browser you will see the tags are escaped:

window.__INITIAL_STATE__ = {"url":"/","xss":"\"\\u003C\\u002Fscript\\u003E\\u003Cscript\\u003Ealert('Possible XSS vulnerability from user input!')\\u003C\\u002Fscript\\u003E\""};

Cheers. 😏

Reference

Building Single Page Applications on ASP.NET Core with JavaScriptServices Use JavaScriptServices to Create Single Page Applications in ASP.NET Core

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].