preface
Recently I have been busy adding the Node middle layer to the project, which is finally available in this release. I’ve been asked this question many times, and in my opinion, there are several reasons:
- Cross-domain problems are avoided
- Make the separation of the front and back end clearer, the back end is responsible for providing data, the front end only needs to pay attention to the EFFECT of the UI layer, part of the logic can be migrated to the middle layer processing
- The domain name of the back-end interface is also protected. After the project is started, the interface displayed in the browser is the interface that passes the middle-layer forwarding
Without further ado, let’s see the implementation
Project address: github.com/huisunyang/…
Deploy the Node project and the Vue project under the same route
Create express project
Here we use Express as the technical framework
Create a new folder nodemiddle
npm init
Copy the code
Enter all the way down
npm install express
npx express-generator
npm install
Copy the code
Follow these steps to complete the initialization of the Express project
Create a VUE project
Initialize the VUE project in the newly created Nodemiddle folder
vue create hello-world
Copy the code
Mix the two items together
Install the connect-History-API-Fallback middleware
npm install --save connect-history-api-fallback
Copy the code
Once installed, switch to the Hello-world directory
npm run build
Copy the code
Generate folder dist
Then modify app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine'.'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// we commented out the two lines ----------------
// app.use('/', indexRouter);
// app.use('/users', usersRouter);
//---------------------------------------------
// ---------------- these three lines are newly added to -----------
var history = require('connect-history-api-fallback');
app.use(express.static(path.join(__dirname, './hello-world/dist')));
app.use(history());
//---------------------------------------------
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') = = ='development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Copy the code
Switch to the root directory and run the project to see the results
Express Enables the HTTPS service
Due to our project, HTTPS service must be enabled locally
Check if you have OpenSSL (if you have Git installed)
openssl version -a
Copy the code
Generating a Certificate File
#1Run the openssl genrsa -out privatekey.pem command to generate the privatekey file1024
#2Use the private key to generate the CSR certificate signature. (Some information is required and press Enter.) openSSL req -new -key privatekey.pem -out certrequest.csr
#3Openssl x509 -req - Generates a certificate file using the private key and certificate signaturein certrequest.csr -signkey privatekey.pem -out certificate.pem
Copy the code
The third command will prompt Signature OK, indicating success
Then we modify the app.js file
// Comment out this line
// module.exports = app;
// Change to the following
var options = {
key: fs.readFileSync('./ssl/privatekey.pem'),
cert: fs.readFileSync('./ssl/certificate.pem')}; https.createServer(options, app).listen(8443.function () {
console.log('Https server listening on port ' + 8443);
});
Copy the code
At this point we can start the HTTPS service locally
Interface forwarding implementation
Since the graphQL interface is used in our project, I will simply implement graphQL interface forwarding. Since I have not dealt with forwarding as resetful, I made a layer of transformation here, calling graphQL interface in Express. But the Resetful interface is provided to the VUE project
First download dependencies
npm i apollo-fetch
Copy the code
Modify the app. Js
const { createApolloFetch } = require('apollo-fetch');
app.get('/graphql'.(request,response) = > {
const fetch = createApolloFetch({
uri: 'http://localhost:8080/graphql'}); fetch({query: '{ hello}',
}).then(res= > {
console.log(res)
})
})
Copy the code
The graphQL interface provided here is a demo of my simple implementation, see github.com/huisunyang/…
Exception handling
Since forward interface, so must without exception handling, which may be embarrassing is express have no way to deal directly with the promise is unusual, usually an error UnhandledPromiseRejectionWarning here I take is to modify the routing component
const Layer = require('express/lib/router/layer');
Object.defineProperty(Layer.prototype, 'handle', {
enumerable: true.get() {
return this.__handle;
},
set(fn) {
if (fn.length === 4) {
this.__handle = fn;
} else {
this.__handle = (req, res, next) = >
Promise.resolve()
.then(() = >fn(req, res, next)) .catch(next); }}})Copy the code
Add the above code and you can handle the exception directly
app.get('/test'.(request,response) = > {
axios.get('http://localhost:3000/test').then(res= > {
response.send(res.data)
}).catch(error= > {
response.status(error.response.status).send(error)
})
})
Copy the code
Write in the last
The above is what I did when I added the node middle layer to the Vue project. I am still optimizing it later. Please point out any mistakes, thank you!!