Ajax request limit: Ajax can only send requests to its own server.
If two pages have the same protocol, domain name and port, the two pages belong to the same source. As long as one of them is different, it is a different source.
For example: http://www.example.com/dir/page.html
- http://www.example.com/dir2/other.html : homologous http://example.com/dir/other.html : different sources (different domain names)
- http://v2.www.example.com/dir/other.html : different sources (different domain names)
- http://www.example.com:81/dir/other.html : different sources (different ports)
- https://www.example.com/dir/page.html : different sources (different protocols)
Purpose of homology policy: homology policy is to ensure the security of user information and prevent malicious websites from stealing data. The original homology policy refers to the cookies set by website A on the client, and website B cannot be accessed.
With the development of the Internet, the homology policy is becoming more and more strict. In the case of different sources, one of the provisions is that Ajax requests cannot be sent to non homologous addresses. If requested, the browser will report an error.
1, Using JSONP to solve the problem of homology restriction
jsonp is the abbreviation of json with padding. It does not belong to Ajax requests, but it can simulate Ajax requests.
1. Write the server-side request address of different origin in the src attribute of the script tag
<script src="www.example.com"></script>//Using the characteristics of script tags, it is not affected by the homology policy
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
2. The server-side response data must be a function call, and the data really sent to the client needs to be used as the parameters of the function call.
const data = 'fn({name: "Zhang San", age: "20"})'; res.send(data);
3. Define the function fn under the global scope of the client
function fn (data) { }
4. Process the data returned by the server inside the fn function
function fn (data) { console.log(data); }
JSONP code optimization
- The client needs to pass the function name to the server.
- Turn the sending of script request into dynamic request.
- Encapsulate jsonp functions to facilitate request sending.
- res.jsonp method for server-side code optimization.
Case: using jsonp to obtain Tencent weather information
. html code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>use jsonp Get Tencent weather information</title> <link rel="stylesheet" href="/assets/bootstrap/dist/css/bootstrap.min.css"> <style type="text/css"> .container { padding-top: 60px; } </style> </head> <body> <div class="container"> <table class="table table-striped table-hover" align="center" id="box"></table> </div> <script src="/js/jsonp.js"></script> <script src="/js/template-web.js"></script> <script type="text/html" id="tpl"> <tr> <th>time</th> <th>temperature</th> <th>weather</th> <th>wind direction</th> <th>wind power</th> </tr> {{each info}} <tr> <td>{{dateFormat($value.update_time)}}</td> <td>{{$value.degree}}</td> <td>{{$value.weather}}</td> <td>{{$value.wind_direction}}</td> <td>{{$value.wind_power}}</td> </tr> {{/each}} </script> <script> // Get table tag var box = document.getElementById('box'); function dateFormat(date) { var year = date.substr(0, 4); var month = date.substr(4, 2); var day = date.substr(6, 2); var hour = date.substr(8, 2); var minute = date.substr(10, 2); var seconds = date.substr(12, 2); return year + 'year' + month + 'month' + day + 'day' + hour + 'Time' + minute + 'branch' + seconds + 'second'; } // Opening external variables to templates template.defaults.imports.dateFormat = dateFormat; // Obtain weather information from the server jsonp({ url: 'https://wis.qq.com/weather/common ', / / request address data: { source: 'pc', weather_type: 'forecast_1h',//Next 48 hours // weather_type: 'forecast_1h|forecast_24h ', / / next 48 hours | next 7 days province: 'Heilongjiang Province', city: 'Harbin City' }, success: function (data) { var html = template('tpl', {info: data.data.forecast_1h}); box.innerHTML = html; } }) </script> </body> </html>
app.js code
// Introducing express framework const express = require('express'); // Path processing module const path = require('path'); // A module that requests data from other servers const request = require('request'); // Create web server const app = express(); // Static resource access service function app.use(express.static(path.join(__dirname, 'public'))); app.get('/server', (req, res) => { request('http://localhost:3001/cross', (err, response, body) => { res.send(body); }) }); // Listening port app.listen(3000); // Console prompt output console.log('The server started successfully');
2, CORS cross domain resource sharing
CORS: the full name is cross origin resource sharing, that is, cross domain resource sharing. It allows browsers to send Ajax requests to cross domain servers, overcoming the limitation that Ajax can only be used from the same source. If the server agrees to the request, it will add {access control allow origin in the response header. If it does not agree, it will not add.
origin: http://localhost:3000
//There are two types that may be returned: 1. The original information of the client; 2. The asterisk* Access-Control-Allow-Origin: 'http://localhost:3000' Access-Control-Allow-Origin: '*'
Example code of setting response header on Node server side:
app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST'); next(); })
3, Accessing non homologous data - server side solution
The homology policy is the restriction of Ajax technology given by the browser, and there is no homology policy restriction on the server.
4, Cookies
Equivalent to ID card, which can confirm who the client is.
withCredentials property
- When sending a cross domain request using Ajax technology, cookie information will not be carried in the request by default.
- withCredentials: Specifies whether to carry cookie information when cross domain requests are involved. The default value is false
- (field carried in response header) access control allow credentials: true allows the client to carry cookie s when sending requests
Case: simulate cross domain login function
html code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Realize cross domain function</title> <link rel="stylesheet" href="/assets/bootstrap/dist/css/bootstrap.min.css"> <style type="text/css"> .container { padding-top: 60px; } </style> </head> <body> <div class="container"> <form id="loginForm"> <div class="form-group"> <label>user name</label> <input type="text" name="username" class="form-control" placeholder="enter one user name"> </div> <div class="form-group"> <label>password</label> <input type="password" name="password" class="form-control" placeholder="Please enter your password"> </div> <input type="button" class="btn btn-default" value="Sign in" id="loginBtn"> <input type="button" class="btn btn-default" value="Detect user login status" id="checkLogin"> </form> </div> <script type="text/javascript"> // Get login button var loginBtn = document.getElementById('loginBtn'); // Get detection login status button var checkLogin = document.getElementById('checkLogin'); // Get login form var loginForm = document.getElementById('loginForm'); // Add click event for login button loginBtn.onclick = function () { // Convert html form to formData form object var formData = new FormData(loginForm); // Creating ajax objects var xhr = new XMLHttpRequest(); // Configuring ajax objects xhr.open('post', 'http://localhost:3001/login'); // When a cross domain request is sent, the cookie information is carried xhr.withCredentials = true; // Send request and pass request parameters xhr.send(formData); // Listen for the response given by the server xhr.onload = function () { console.log(xhr.responseText); } } // When the detect user status button is clicked checkLogin.onclick = function () { // Creating ajax objects var xhr = new XMLHttpRequest(); // Configuring ajax objects xhr.open('get', 'http://localhost:3001/checkLogin'); // When a cross domain request is sent, the cookie information is carried xhr.withCredentials = true; // Send request and pass request parameters xhr.send(); // Listen for the response given by the server xhr.onload = function () { console.log(xhr.responseText); } } </script> </body> </html>
app.js
// Introducing express framework const express = require('express'); // Path processing module const path = require('path'); // Receive post request parameters const formidable = require('formidable'); // Realize session function var session = require('express-session'); // Create web server const app = express(); // Receive post request parameters // Realize session function app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false })); // Static resource access service function app.use(express.static(path.join(__dirname, 'public'))); // Block all requests // app.use((req, res, next) => { // // 1. Which clients are allowed to access me // //* allow all clients to access me // res.header('Access-Control-Allow-Origin', '*') // // 2. What request methods are allowed for clients to access me // res.header('Access-Control-Allow-Methods', 'get,post') // next(); // }); app.get('/test', (req, res) => { const result = 'fn({name: "Zhang San"})'; res.send(result); }); app.get('/better', (req, res) => { // The name of the function passed from the receiving client //const fnName = req.query.callback; // Return the function call code corresponding to the function name to the client //const data = JSON.stringify({name: "Zhang San"}); //const result = fnName + '('+ data +')'; // setTimeout(() => { // res.send(result); // }, 1000) res.jsonp({name: 'lisi', age: 20}); }); app.get('/cross', (req, res) => { res.send('ok') }); // Block all requests app.use((req, res, next) => { // 1. Which clients are allowed to access me // *Allow all clients to access me // Note: if cookie information transfer is involved in the cross domain request, the value cannot be * sign, such as specific domain name information res.header('Access-Control-Allow-Origin', 'http://localhost:3000') // 2. What request methods are allowed for clients to access me res.header('Access-Control-Allow-Methods', 'get,post') // Allow the client to carry cookie information when sending cross domain requests res.header('Access-Control-Allow-Credentials', true); next(); }); app.post('/login', (req, res) => { // Create form resolution object var form = formidable.IncomingForm(); // Parse form form.parse(req, (err, fields, file) => { // Receive the user name and password passed by the client const { username, password } = fields; // User name password comparison if (username == 'itheima' && password == '123456') { // Set session req.session.isLogin = true; res.send({message: 'Login succeeded'}); } else { res.send({message: 'Login failed, Wrong user name or password'}); } }) }); app.get('/checkLogin', (req, res) => { // Judge whether the user is logged in if (req.session.isLogin) { res.send({message: 'Is logged in'}) } else { res.send({message: 'Not logged in'}) } }); // Listening port app.listen(3001); // Console prompt output console.log('The server started successfully');