当前位置:网站首页>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);
边栏推荐
- JS scale down the width and height of the picture
- Pseudo static setting of access database in win2008 R2 iis7.5
- MySQL performance test (slow query log)
- PHP: seven cattle cloud upload file
- A snare - Cookie spoofing
- Building 64 bit wampserver and DVWA in win7 virtual machine
- 深度学习与CV教程(14) | 图像分割 (FCN,SegNet,U-Net,PSPNet,DeepLab,RefineNet)
- 蓝桥杯2015年CA省赛(填坑中)
- 3. Abstract Factory
- Download Notepad++
猜你喜欢

Valentina Studio Pro for MAC (MAC database management software)

MySQL performance test (slow query log)

2022京東618預售定金怎麼退?京東618定金能退嗎?

3. Abstract Factory

Getting started with cloud API basics -- basic knowledge of picgo writing plug-ins

Student management system

2022京东618预售定金怎么退?京东618定金能退吗?

Telecommuting with cpolar (2)

Pycharm view the current version of opencv

Valentina Studio Pro for Mac(mac数据库管理软件)
随机推荐
基于QT的旅行查询与模拟系统
Leetcode 2169. Get operands of 0
Fiddler automatically saves the result of the specified request to a file
How to refund the pre-sale deposit of JD 618 in 2022? Can JD 618 deposit be refunded?
Machine learning is not something you can use if you want to use it
Stream as a return value in WCF - who disposes of it- Stream as a return value in WCF - who disposes it?
Vscode code debugging skills
JS string combination
基于C#的安全聊天工具设计
高通平台如何修改特殊电压
2021-03-24
卡鱼刺别再喝醋吞米饭了!教你2招,让鱼刺安全“跑出来”
The name of a great man
Why check the @nonnull annotation at run time- Why @Nonnull annotation checked at runtime?
93. obtain all IP addresses of the Intranet
VSCode代码调试技巧
Bug easily ignored by recursion
Building 64 bit wampserver and DVWA in win7 virtual machine
Class selectors and using pseudo class selectors with
Jump to wechat in app and open wechat