Let me show you how to use nginx for front-end cross-domain access using a simple pair of Node servers.
- Node1 server starts on localhost: 8083
const app = express();
app.get('/web/users',(req, res)=>{
res.json([{name:"Zhang",age:12},{name:"Bill",age:14}]);
res.end()
})
app.listen(process.env.PORT || 8083);
Copy the code
The front-end code in the domain only needs to be called
function getUsers() {
var xhr=new XMLHttpRequest();
xhr.open('GET'.'http://localhost:8083/web/users');
xhr.send(null);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}else{ alert(xhr.statusText); }}}Copy the code
There is a small bit of concern is that under the code in the same domain before and after the end, XHR. The open () also can url path as follows, it will be the default request to http://localhost:8083/web/users
xhr.open('GET'.'/web/users');
Copy the code
Now we remove the Web/Users interface from the node1 server:
const app = express();
app.listen(process.env.PORT || 8083);
Copy the code
The front-end cannot access the backend Web/Users, and a 404 error will be reported.
Add a node2 server, start on localhost:8085, and move the web/ Users interface that was removed on 8083 to 8085:
const app = express();
app.get('/web/users',(req, res)=>{
res.json([{name:"Zhang",age:12},{name:"Bill",age:14}]);
res.end()
})
app.listen(process.env.PORT || 8085);
Copy the code
Since 8085 implements this interface, we’ll try calling it with Ajax under port 8083:
xhr.open('GET'.'http://localhost:8085/web/users');
Copy the code
As expected, the browser blocks the behavior and throws a cross-domain error.
Can’t you access that interface? In fact, servers can call each other and prevent cross-domain access is only restricted on the browser side.
Here I implement how to access the Web/Users interface on 8085 in two ways.
1. Node directly acts as a proxy
The principle is to access 8085 port interface by 8083 back end, access to the front-end 8083node back end implementation code:
NPM install Request --save // An HTTP request module needs to be installedCopy the code
const app = express()
const request = require('request'// Access this interface through the request module to access 8085 and back to the front-end. app.get('/web/users',(req, res)=>{
var url='http://localhost:8085'+req.url
console.log(url) // http://localhost:8085/web/users
req.pipe(request(url)).pipe(res);
})
Copy the code
2. Access in JSONP mode
SRC of the script requests data from the server, which is not restricted by the same origin policy. The server then returns the data to the front end in the specified function callback name. 8083 front-end request 8085, here is no longer an Ajax request, but directly load 8085 resources.
<script>
function getUsers(data) {
alert(data)
}
</script>
<script src="http://localhost:8085/jsonp? callback=getUsers"></script>
Copy the code
The first script tag in the above code defines a function getUsers but it is not executed, it is just defined. To be able to execute, you need to
getUsers(data)
Copy the code
So we’re going to make the second tag script SRC = “http://localhost:8085/jsonp? Callback =getUsers” returns the getUsers(data) content so that the function defined in the first tag can be executed. Return interface content only need to be put into the function parameters can be implemented in background 8085:
const app = express();
const querystring=require('querystring')
const url=require('url'// Process the front-end JSONp request app.get('/jsonp',(req,res)=>{
var qs = querystring.parse(req.url.split('? ') [1]); //{callback:'getUsers'}
var users=JSON.stringify([{name:"Zhang",age:12},{name:"Bill",age:14}]) var callback=${qs.callback}(${users})`
res.end(callback)
})
Copy the code
The front return
Doesn’t it smell like dark magic?! However, there are also obvious disadvantages. First, there is some security in this method, and there is the possibility of XSS attacks by adding some mess after passing callback. Most importantly, JSONP does not support POST methods.
3. Nginx reverse proxy
This method is similar to the first node proxy method, also through the server to server communication, but does not need to 8083 under the background server to access 8085, but exclusively to nginx, why? Let’s just say nginx is more professional! Nginx configuration
server {
listen 8007; # nginx startup port, which needs to be accessed to be able to proxy
server_name localhost:8083; The server that requires the proxy
location / { # If you access 127.0.0.1/8002/ then nginx will request it
proxy_pass http://localhost:8083;
}
location /web { # access/web/aa will be mapped to http://localhost:8085/web/aa;proxy_pass http://localhost:8085; }}Copy the code
8083 Request path
xhr.open('GET'.'/web/users');
Copy the code
3 CORS
CORS is a W3C standard, which stipulates that browsers allow ajax to be sent to servers in different domains to obtain data, thus overcoming the original limitation. Using CORS requires the support of both the front and back ends, which is basically supported by modern browsers. Specific knowledge of CORS can reference nguyen other blog www.ruanyifeng.com/blog/2016/0…
app.use(The '*'.function (req, res, next) {
res.header('Access-Control-Allow-Origin'.The '*'); // This indicates that any domain name can be accessed. //res.header('Access-Control-Allow-Origin'.'http://www.baidu.com'); // Write so that only www.baidu.com can be accessed. res.header('Access-Control-Allow-Headers'.'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header('Access-Control-Allow-Methods'.'PUT, POST, GET, DELETE, OPTIONS'); // Set methodif (req.method == 'OPTIONS') {
res.send(200);
}
else{ next(); }});Copy the code
Or use an off-the-shelf CORS module
npm install cors
Copy the code
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://www.baidu.com',
optionsSuccessStatus: 200
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({msg: 'Only Baidu can access it'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')})Copy the code
Please correct ^_^ if any is incorrect