当前位置:网站首页>Several solutions across domains
Several solutions across domains
2022-06-12 10:37:00 【dralexsanderl】
Several solutions across domains
What is cross-domain ?
When a request url The agreement 、 domain name 、 Any one of the three ports and the current page url Difference is cross domain .
Why is there a cross domain problem ?
Due to the restriction of browser's homology policy . The same origin policy is a convention , It is the core and most basic security feature of the browser , If the same origin policy is missing , Browsers are easily accessible XSS、CSRF Such attacks . Even if two different domains point to the same one ip Address , Nor a homologous . The same origin policy will prevent a domain from javascript The script interacts with the contents of another domain . The so-called homology ( I mean in the same domain ) Two pages have the same protocol (protocol), host (host) And port number (port).
The same origin policy limits the content to have :
Cookie、LocalStorage、IndexedDBAnd other storage contentDOMnodeAJAXAfter the request is sent , It was blocked by the browser
There are three tags that allow cross domain loading of resources :
<img src=XXX><link href=XXX><script src=XXX>
Cross-domain is not a request that cannot be sent , The request can be sent , The server receives the request and returns the result as normal , Only the result was blocked by the browser
Solution
1. CORS
CORS It's cross domain resource sharing (Cross-Origin Resource Sharing) Abbreviation . It is W3C standard , It belongs to cross source AJAX The fundamental solution to the request .CORS Requires both browser and backend support .
Server settings Access-Control-Allow-Origin I can turn it on CORS. This property indicates which domain names can access the resource , If you set wildcards (*) It means that all websites can access resources , No cross domain access is required .
router.get('/cors', (req, res, next) => {
// Only 127.0.0.1:8080
res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:8080');
// res.setHeader('Access-Control-Allow-Origin', '*');
res.json(data);
});
2. jsonp
utilize <script> Tags have no cross-domain limitations , stay script In the tag, we can refer to scripts on other services , The most common scenario is CDN.
technological process :
- On the client side , You can first define a callback to receive the
javascript. - Create a... In the client
scriptlabel , Put itsrcProperty points to the corresponding interface . And take the callback function name defined in the first step as the request parameter . - Process the request in the server , take
javascriptFile incoming callback . - The client receives the response data and executes the
javascript.
client
// 1. Create callback function callback
function callback(res) {
console.log(JSON.stringify(res, null , 2));
}
// 2. Dynamically create script label , And set up src attribute , Pay attention to the parameters cb=callback
var script = document.createElement('script');
script.src = 'http://127.0.0.1:3000/info/jsonp?cb=callback';
document.getElementsByTagName('head')[0].appendChild(script);
Server side :
router.get('/jsonp', (req, res, next) => {
var str = JSON.stringify(data);
// 3. establish script The script content , use `callback` Functions wrap data
// form :callback(data)
var script = `${
req.query.cb}(${
str})`;
res.send(script);
});
// 4. The front end will automatically execute the script after receiving the response data
jsonp Only support GET Method
3. websocket
Websocket yes HTML5 A persistent protocol , It enables full duplex communication between the browser and the server , It is also a cross-domain solution .WebSocket and HTTP These are application layer protocols , Are based on TCP agreement . however WebSocket It is a two-way communication protocol , After establishing the connection ,WebSocket Of The server and Clients can actively send or receive data to each other . meanwhile ,WebSocket You need help when you're making connections HTTP agreement , Once the connection is established client And server Two-way communication between and HTTP Has nothing to do .
client
let socket = new WebSocket('ws://localhost:3000');
socket.onopen = function () {
socket.send('connect');// Send data to the server
}
socket.onmessage = function (e) {
console.log(e.data);// Receive the data returned by the server
}
Server side
let express = require('express');
let app = express();
let WebSocket = require('ws');
let wss = new WebSocket.Server({
port:3000});
wss.on('connection',function(ws) {
ws.on('message', function (data) {
ws.send(data)
});
})
4. Using agents
This approach essentially still follows the same origin policy , Just changed the idea of a request , Moved the request to the back end .
The same origin policy is a browser level restriction . that , If we don't cross domain on the front end , And will be “ Cross domain ” The task of is left to the back-end service , Then we have evaded the homologous policy .
router.get('*', (req, res, next) => {
let path = req.path.replace(/^\/proxy/, '');
request.get(`http://127.0.0.1:3002${
path}`, (err, response) => {
res.json(JSON.parse(response.body));
});
});
5. Nginx agent
The implementation principle is similar to the above proxy . Is to build a transit nginx The server , Used to forward requests .
Use nginx Reverse proxy implementation across domains , It's the easiest way to cross domains . It just needs to be modified nginx Is configured to solve cross-domain problems , Support for all browsers , Support session, You don't need to change any code , It does not affect server performance .
We just need to configure nginx, Configure multiple prefixes on a server to forward http/https Request to multiple real servers . such , All on this server url Are the same domain name 、 Protocol and port . therefore , For browsers , these url Are homologous , No cross domain restrictions . But in fact , these url In fact, the service is provided by the physical server . In these servers javascript All of these servers can be called across domains url.
To download nginx, And then nginx In the catalog nginx.conf Revised as follows :
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; # Reverse proxy
proxy_cookie_domain www.domain2.com www.domain1.com; # modify cookie In the domain name
index index.html index.htm;
# When used webpack-dev-server Such as middleware proxy interface access nignx when , No browser is involved at this time , So there is no homologous restriction , The following cross-domain configuration is not enabled
add_header Access-Control-Allow-Origin http://www.domain1.com; # The current end is cross-domain only cookie when , for *
add_header Access-Control-Allow-Credentials true;
}
}
6. postMessage
postMessage yes HTML5 XMLHttpRequest Level 2 Medium API, And is one of the few that can operate across domains window One of the attributes .
call postMessage Method to implement the parent window http://test1.com To child window http://test2.com Send a message ( The child window can also send messages to the parent window through this method )
It can be used to solve the following problems :
- Data transfer for the page and the new window it opens
- Message passing between multiple Windows
- Page with nested iframe The messaging
- Cross domain data transfer for the above three scenarios
postMessage() Method allows scripts from different sources to communicate asynchronously for limited amounts , Cross-text files can be implemented 、 Many window 、 Cross-domain messaging .
grammar :otherWindow.postMessage(message, targetOrigin, [transfer]);
- message: Will be sent to others window The data of .
- targetOrigin: windowed origin Property to specify which Windows can receive message events , The value can be a string "*"( Means unlimited ) Or a URI. When sending a message , If the target window of the protocol 、 The host address or port does not match any of the three targetOrigin Provide the value of the , Then the message will not be sent ; Only three of them match perfectly , The message is sent .
- transfer( Optional ): It is a list of and message Simultaneous transitive Transferable object . Ownership of these objects is transferred to the recipient of the message , The sender will no longer retain ownership .
http://localhost:8080/a.html Page to http://localhost:8090/b.html To send messages .
<!-- http://localhost:8080/a.html -->
<iframe src="http://localhost:8090/b.html" frameborder="0" id="frame" onload="load()"></iframe> // Triggers an event after it has loaded
// Embedded in http://localhost:8080/a.html
<script> function load() {
let frame = document.getElementById('frame') frame.contentWindow.postMessage('request', 'http://localhost:8090') // send data window.onmessage = function(e) {
// Accept returned data console.log(e.data) // I do not love you } } </script>
// http://localhost:8090/b.html
window.onmessage = function(e) {
e.source.postMessage('response', e.origin)
}
7. document.domain + iframe
This method can only be used in the case of the same secondary domain name , such as a.test.com and b.test.com Apply to this approach .
Just add to the page document.domain ='test.com' Means that the secondary domain name is the same can achieve cross-domain .
Realization principle : Both pages passed js Force settings document.domain Is the base primary domain , I'm going to implement the same domain .
http://a.localhost:8080/a.html Page to http://b.localhost:8080/b.html To send messages .
<!-- http://a.localhost:8080/a.html -->
<iframe src="http://b.localhost:8080/b.html" frameborder="0" id="frame" onload="load()"></iframe> // Triggers an event after it has loaded
// Embedded in http://localhost:8080/a.html
<script> document.domain = 'localhost:8080' function load() {
console.log(frame.contentWindow.a); } </script>
// http://b.localhost:8080/b.html
document.domain = 'localhost:8080';
var a = 100;
8. window.name + iframe
window.name Unique attributes :name Values on different pages ( Even different domains ) It still exists after loading , And can support very long name value (2MB).
among a.html and b.html Is the same domain , All are http://localhost:3000; and c.html yes http://localhost:4000
// a.html(http://localhost:3000/b.html)
<iframe src="http://localhost:4000/c.html" frameborder="0" onload="load()" id="iframe"></iframe>
<script> let first = true // onload Events will trigger 2 Time , The first 1 Load the cross-domain page , And keep the data window.name function load() {
if(first){
// The first 1 Time onload( Cross-domain pages ) After success , Switch to the same domain proxy page let iframe = document.getElementById('iframe'); iframe.src = 'http://localhost:3000/b.html'; first = false; }else{
// The first 2 Time onload( The same domain b.html page ) After success , Read the same domain window.name Data in the console.log(iframe.contentWindow.name); } } </script>
b.html Is the intermediate proxy page , And a.html The same domain , Content is empty .
```html
// c.html(http://localhost:4000/c.html)
<script> window.name = ' I do not love you ' </script>
summary : adopt iframe Of src Property from outland to local region , Cross-domain data is defined by iframe Of window.name From outland to local area . This neatly circumvents the browser's cross-domain access restrictions , But it's also a safe operation .
9. location.hash + iframe
Realization principle : a.html with c.html Cross-domain communication , Through the middle page b.html To achieve . Three pages , Between domains iframe Of location.hash Pass value , Direct between the same fields js Access to communicate .
Specific implementation steps : In limine a.html to c.html Pass a hash value , then c.html received hash After value , And then hash The value passed to the b.html, Last b.html Put the result into a.html Of hash In the value .
alike ,a.html and b.html Is the same domain , All are http://localhost:3000; and c.html yes http://localhost:4000
// a.html
<iframe src="http://localhost:4000/c.html#iloveyou"></iframe>
<script> window.onhashchange = function () {
// testing hash The change of console.log(location.hash); } </script>
Copy code // b.html
<script> window.parent.parent.location.hash = location.hash //b.html Put the result into a.html Of hash In the value ,b.html It can be done by parent.parent visit a.html page </script>
// c.html
console.log(location.hash);
let iframe = document.createElement('iframe');
iframe.src = 'http://localhost:3000/b.html#idontloveyou';
document.body.appendChild(iframe);
边栏推荐
猜你喜欢
![[experiment] MySQL master-slave replication and read-write separation](/img/aa/7d0799013ff749cacf44ba3b773dff.png)
[experiment] MySQL master-slave replication and read-write separation

How to play the 2022 Taobao 618 Super Cat Games? Playing skills of 2022 Taobao 618 Cat Games

Chapter 3 search

MySQL performance test (slow query log)

On the improvement of 3dsc by harmonic shape context feature HSC

4. creator mode

A hundred secrets and a few secrets - Caesar encryption

Common methods of string class

QT custom window fillets

2022淘宝618超级喵运会玩法攻略 618超级喵运会玩法技巧
随机推荐
基于QT的旅行查询与模拟系统
PHP get (remote) large file method record
Pycharm view the current version of opencv
MySQL user and permission management, role management
验收标准到底是不是测试用例?
Error during session start; please check your PHP and/or webserver log file and configure your PHP
Assign a specified amount to a specified number of people at random
PHP interface generates cache and MD5 encryption uniformly
容器江湖的爱恨情仇
Php:redis uses geospatial
session_ start(): Cannot send session cache limiter - headers already sent
PHP maximum balance method to solve the problem that the sum of the final percentages is not equal to 100
Getting started with cloud API basics -- basic knowledge of picgo writing plug-ins
Composer command
The most detailed explanation of the top ten levels of sqli labs platform
Global and local existence of array, integer and character variables
ASP. Net core permission system practice (zero)
Properties Chinese garbled code
How to play the 2022 Taobao 618 Super Cat Games? Playing skills of 2022 Taobao 618 Cat Games
Love and hate in the Jianghu