AJAX cross-domain solutions
This is the 22nd day of my participation in the August Wen Challenge.More challenges in August
1. Separation mode of front and rear ends
- Static Resources (HTML) –
server-a
Provide front-end static resources. - Back-end data (commodity information…) –
server-b
Offer based onHTTP
的API
.
2. Same-origin policy
The same origin policy protocol is triggered when we use XHR to fetch data from one source to another.
The source
Domain: protocol + host (IP address or domain name) + port, for example, http://localhost:8888.
The same-origin policy
A security mechanism used by browsers to prevent the use of scripts to obtain non-homogeneous data.
3. Cross-domain solution: CORS
This mechanism is built on a core content: HTTP headers. This mechanism defines a set of HTTP headers through which access to resources is controlled. These HTTP headers are basically access-Control -? Different HTTP headers have different functions.
Reference: developer.mozilla.org/zh-CN/docs/…
Common Resource request
Access-Control-Allow-Origin
Controls the origin that is currently allowed to access the resource.
Non-ordinary resource request
Simple request & Non-simple request
If the request meets certain rules, it is a simple request
Reference: developer.mozilla.org/zh-CN/docs/…
Preview the request
If the current request meets the non-simple request, a request (browser) with method options is sent first, which is called precheck. The back end needs to process the precheck request and return the corresponding header information according to the service to inform the client whether to allow the non-simple request. We need to return a series of headers in the precheck request to control whether the previously sent non-simple request continues
Reference: developer.mozilla.org/zh-CN/docs/…
4. Cross-domain solution: back-end proxy
In addition to js being able to send HTTP requests through some API, many other languages can do this, so can Node.js. Node.js is not restricted by the same origin policy, so we can use static resources (i.e. the resource server from which THE JS request is sent) to send the request and then forward it. We call it: agent.
Provide API service server: ServerA
Source: http://localhost:8888
const Koa = require('koa');
const KoaRouter = require('koa-router');
const app = new Koa();
const router = new KoaRouter();
router.get('/data'.async (ctx, next) => {
ctx.body = [1.2.3.4.5];
})
app.use(router.routes());
app.listen(8888);
Copy the code
The server that sends THE JS request: ServerB
const Koa = require('koa');
const KoaStaticCache = require('koa-static-cache');
const KoaRouter = require('koa-router');
const http = require('http');
const app = new Koa();
app.use(KoaStaticCache({
prefix: ' '.dir: './public'.gzip: true.dynamic: true
}));
// Cross-domain issues: browsers have same-origin policy restrictions, but not necessarily others. Many languages have web-based programming that can listen for requests,
// Requests can also be sent, and there is generally no same-origin policy by default
// We can provide HTTP modules based on Node to send requests
// This URL is the forward interface to send ajax requests to our current js server
router.get('/data'.async (ctx, next) => {
// Use to send an HTTP request to the real server interface
// Back-end proxy
// [server1.ajax => server1] => server2, server1 is the proxy
return new Promise((resolve, reject) = > {
let req = http.request({
// method: 'get',
hostname: 'localhost'.port: 8888.path: '/data'
}, (res) = > {
let data = ' ';
res.on('data'.(chunk) = > {
data += chunk.toString();
});
res.on('end'.() = > {
console.log('Data:', data);
ctx.body = data;
resolve();
});
});
req.write(' '); req.end(); })}); app.use(router.routes()); app.listen(9999);
Copy the code
JS request in ServerB
let xhr = new XMLHttpRequest();
// Data must add the address of the current js server
xhr.open('/get'.'/data');
xhr.onload = function() {
console.log(this.responseText);
}
xhr.send();
Copy the code
5. Cross-domain certificate information processing
5-1, based onCookie
的 CORS
To deal with
Cookies are also restricted by the same origin policy. If a request is not from the same origin, cookies are prohibited by default.
Request with credentials
- The client sets the following parameters in the request:
withCredentials: true
- The server should be set in CORS:
ctx.set('Access-Control-Allow-Credentials', 'true');
5-2, based onToken
The authentication mechanism of the
Cookie-based authentication has some problems:
- Whether or not the current request needs to be delivered
Cookie
, the browser will actively send (waste). - Easy to be
CSRF
Attack.
The 5-2-1,JWT
introduce
Json Web Token (JWT) is an open jSON-based standard implemented to transfer claims between network application environments.
Reference: JWT. IO/introductio…
Composition structure:
JWT is made up of three pieces of text linked by a
let header = `{ "alg": "HS256", "typ": "JWT" }`;
let payload = `{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }`;
let key = '* * *';
let sign = HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
key
);
let token = `${base64UrlEncode(header)}.${base64UrlEncode(payload)}.${sign}`;
Copy the code
Token content generated:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.E1H9eRej 3pbltuEr9IL12jJjb-612z_q1eEfvNKK0t8Copy the code
header
ALGORITHM & TOKEN TYPE, which TYPE and the ALGORITHM used.
payload
Stored data
sign
The signature
In the 5-2-2 s, the use ofJWT
We can use JsonWebToken to implement token generation and validation
npm install jsonwebtoken
Copy the code
/ / the back end.const jwt = require('jsonwebtoken');
const signKey = '* * *'; . router.post('/login'.async (ctx, next) => {
let user = {id: 1.username: 'zMouse'};
const token = jwt.sign(user, signKey);
// Send through header Authorization
ctx.set('Authorization', token);
ctx.body = 'Login successful';
})
router.get('/user/profile'.async (ctx, next) => {
let user = null;
try {
let
let token = ctx.get('Authorization');
user = jwt.sign(token, signKey);
if(! user) { ctx.throw(401.'No access');
}
ctx.body = 'Accessible'; }})...Copy the code
After the client successfully requests login, it obtains the token, which can be saved in the client using methods such as localStorage.
function login() {
let xhr = new XMLHttpRequest();
xhr.open('post'.'/login');
xhr.onload = function() {
if ( xhr.status >= 200 && xhr.status < 300 ) {
let token = xhr.getResponseHeader('Authorization');
localStorage.setItem('token', token);
}
}
xhr.send(JSON.stringify({username:'Kobe Bryant'.password: '123456'}));
}
function getUserProfile() {
let xhr = new XMLHttpRequest();
xhr.open('get'.'/user/profile');
xhr.onload = function() {
console.log(xhr.responseText);
}
let token = localStorage.getItem('token');
xhr.setRequestHeader('Authorization'.`Bearer ${token}`);
xhr.send();
}
Copy the code
6. Fetch request
The Fetch API provides an interface to Fetch resources (including cross-domain requests). Anyone who has ever worked with XMLHttpRequest should be able to get started, and the new API offers a much more powerful and flexible set of features. Some definitions of common objects are also provided:
- Reuqest
- An object that operates on a resource request.
- Response
- The object that operates on the response resource.
- Headers
- An object that retrieves, sets, adds, deletes, and so on header information.
const myHeaders = new Headers();
myHeaders.append('Content-Type'.'application/json');
const myRequest = new Request('/user', {
method: 'post'.headers: myHeaders,
body: JSON.stringify({username: 'Kobe Bryant'.password: '123456'})});// res => Response object
let res = await fetch(myRequest);
let data = await res.json();
// let data = await res.text();
Copy the code
XMLHttpRequest Vs Fetch
XMLHttpRequest
- Support for request and response progress events
- Support request cancellation:
abort
Fetch
- More standard, standard
API
Support.Header
、Request
、Response
、Promise
、CORS