Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

preface

As a developer, I’m sure you hear the word cross-domain a lot, both on projects and in interviews. You’re more or less familiar with cross-domain. So how many cross-domain approaches do you know? Leave a comment in the comments section.

What is cross-domain?

For security reasons, the browser only allows access to scripts and interfaces that request the same domain name, same port, and same protocol. If a protocol, domain name, or port is not met, it will cause cross-domain.

Browsers implement a common security pattern -> same origin policy

URL instructions Whether to allow communication
www.baidu.com/banner.js

www.baidu.com/search.js
Under the Same Domain Allow communication
www.baidu.com:8080/detail.js

www.baidu.com/8000/apollo…
Different ports for the same domain name Disallow communication
www.baidu.com/test/date-r…

www.baidu.com/utils/valid…
In different folders under the same domain name Allow communication
www.google.com/banner.js

www.google.com/search.. js
Different protocols for the same domain name Disallow communication
Bytedance.wenjuan.com/userInfo/qu…

Live.wenjian.com/userInfo/qu…
Same primary domain different subdomains Disallow communication
http://12.35.46.87/login.js

blog.mintureChan/login.js
The domain name is the same as the IP address of the domain name Cross-domain is not allowed
blog.mintureChan/login.js

http://mintureChan/login.js
The domain name is the same. The secondary domain name is different Cross-domain is not allowed
www.baidu.com/banner.js

www.google.com/banner.js
Different domain name Cross-domain is not allowed

The above is a comparison of different communication requests.

The same-origin policy

The same origin policy, which is a famous security policy proposed by Netscape.

Open baidu and Google respectively on the Browser TAB page

When the browser TAB executes a script, it checks which page the script belongs to,

That is, check whether the same origin, only the script and Baidu will be executed.

If it is non-same-origin, the browser raises an exception in the console to deny access when the data is requested.

The same origin policy is a behavior of the browser to protect local data from being contaminated by data retrieved by JavaScript code. Therefore, the same origin policy intercepts data received from the client. That is, the request is sent and the server responds, but the browser cannot receive the request.

Cross-domain solution

jsonp

Jsonp is a usage pattern for JSON. The

Script tags are executed by JavaScript translators rather than parsed by JSON parsers.

// Get fly.js with jsonp
let fly = document.createElement('script')
fly.src = 'https://unpkg.com/flyio/dist/fly.min.js'
document.head.appendChild(fly)
Copy the code

Application scenario: Access packages deployed under different domain names or access third-party SDKS.

Disadvantages of JSONP: JSONP requests only support GET requests. Files transferred by JSONP can lead to XSS attacks.

PostMessage addresses cross-domain

PostMessage is a Web Api window.postMessage() that provides a controlled mechanism to circumvent the same origin security pattern. It can be safe as long as it’s used properly.

PostMessage allows you to send messageEvents from one Iframe to another. The received Page can use window. addEventListener(‘message’,(receiveMessage)=>{//do some thing}) to obtain the message from the post page.

Usage scenario: In a project to communicate with other non-homologous deployment projects. Nested iframe maps in the project to send rider delivery messages. Disadvantages of postMessage: The listener needs to be monitored every time a message is sent. The sender and receiver need to be configured. And the code becomes redundant and bloated under multiple distributions.

CORS(Cross-domain Resource Sharing)

CORS (Cross-Origin Resource Sharing) is a system that consists of a series of transmitted HTTP headers that determine whether the browser prevents front-end JavaScript code from getting a response to a cross-domain request.

By default, the same Origin policy prevents cross-domain access to resources. But CORS gives the Web server this permission, allowing cross-domain requests to access other resources under different sources

When a request is sent using XMLHttpRequest, the browser determines whether the request conforms to the same origin policy. If the request does not meet the same Origin policy, the browser will add a request header -> Origin to the request

Cross-domain resource sharing can be configured either by the back-end or the front-end

// Ajax implements CORS across domains
var xhr = new XMLHttpRequest()
var url = 'https://v1.apicloudMusic/find/detail'
// Whether to carry cookies in the request
xhr.withCredentials = true;

xhr.open('GET',url,false)
// Prerequest response callback
xhr.onreadystatechange = () = >{if(xhr.readyState === 4 && xhr.status ===200) //do some thing }
xhr.send()
Copy the code
// We can handle some of the interfaces that need to cross domains in the Java request interceptor

  / * * import packages: import javax.mail. Servlet. HTTP. HttpServletResponse; * Defined in interface parameters: HttpServletResponse Response */

  // Domain name that can be accessed across domains: Write the full port (protocol + domain name + port) if there is no port, do not add '/' at the end of the port.
  response.setHeader("Access-Control-Allow-Origin"."http://www.domain1.com");
  
  // Allow cookies in the front end: After this parameter is enabled, the domain name cannot be '*'. You must specify a specific domain name, or the browser will prompt you
  response.setHeader("Access-Control-Allow-Credentials"."true");
  
  // The type of request to allow cross-domain access
 response.setHeader("Access-Control-Allow-Method"."POST, GET, PATCH, DELETE, PUT, OPTIONS");
Copy the code

Note that if the front end carries cookies to the request header, the back end must be configuredAccess-Control-Allow-Credentials

Usage scenario: This mode applies to cross-domain requests between different services. It is one of the mainstream cross – domain solutions

Websocket implementation is cross-domain

Both Websocket and HTTP are based on TCP. Therefore, using Websocket to communicate does not need to consider cross-domain issues, but using WebSocket to communicate requires the unique state of webSocket

/ / the client
 npm  i socket.io --save
 
// Assume the page has a DOM with id myH3
var domRender = document.getElementById('myH3')
let io =  require("socket.io")
io.connect('http://localhost:8081');
io.on('data'.(data) = >{
  myH3.innerHTML = data
})
Copy the code
// Use Node as the server to send information to the client
var httpServer = require('http').createServer();
var io = require("socket.io")(httpServer);
httpServer.listen(8080);
io.on("connection".function(client){
// The client sends data
client.emit("data"."hello WebSocket from 8081");
});
Copy the code

This communication method can also be considered as a cross-domain solution

Usage scenario: Used for receiving and sending real-time messages.

Nginx reverse proxy implementation across domains

nginxAs a lightweight high-performance Web server has been loved by countless developers. It is small in size. Extremely capable of concurrency, it is ideal for distribution as a proxy server. Using Nginx as a cross-domain solution is also currently the most widely used approach by developersExample Start a node service with port 8070 locally

Let’s say it’s local9998The console will report a cross-domain error if the port runs the HTML file shown above. We use the Nginx reverse proxy to solve this problem.

downloadnginx nginxConfiguration is typically done by back-end developers. And it’s generally usedlinuxVersion for convenience I’ll use it herewindowVersion of thenginxconfigure

You will find these folders in the nginx directory as shown above. Enter the config file. Find a file called nginx.conf that is the basic configuration file for nginx. Open and modify:

Listening to thelocalhost:9998Port configures a requested proxy. Will all pass under localhost:9998 port/api/Request paths are all proxied tolocalhost:8070Up means accesshttp://localhost:9998/api/getUserInfoThe request actually becomes a request to visithttp://localhost:8070/api/getUserInfoThis address. This method is called reverse proxy.

We restart port 9998 to access the HTML file and the console prints out the response.

Node middleware agents cross domains

The principle of using Node middleware for proxy cross-domain is basically the same as the principle of nginx proxy cross-domain: data is forwarded by a proxy server to achieve same-origin operation.

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

// Access the HTTP-proxy-Middleware proxy server
xhr.open('get'.'http://localhost:9998/findList? query="BTC"'.true);
xhr.send();
Copy the code

Middleware server code:

var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();

app.use('/', proxy({
    // Proxy cross-domain address
    target: 'http://localhost:8070/api/getUserInfo'.changeOrigin: true.// Modify the CORS response header information to achieve cross-domain and allow cookies
    onProxyRes: function(proxyRes, req, res) {
        res.header('Access-Control-Allow-Origin'.'http://localhost:9998');
        res.header('Access-Control-Allow-Credentials'.'true'); }})); app.listen(9998);
console.log('Proxy server is listen at port 9998... ');

Copy the code

webpack-dev-server

If you have used vue-CLI + webpack to build projects then you are familiar with webpack-dev-server. The scaffolding project starts the service locally using webpack-dev-server. You can see the code following NPM run dev in the package.json shortcut command line

In the development environment we usually access other services like file services, audio and video services. It can also cause cross-domain problems. In vuE-cli3 project, we can modify the configuration of devServer in vue.config.js file to solve the cross-domain problem in the development environment.

//vue.config.js 
const target = "http://minture-chan-glitch.com"
module.exports = {
    entry: {},
    module: {},...devServer: {
        port: 8088.open: true.proxy: [
         '/api': {
         //target -> The address of the proxy target
          target,
          ws: true.changeOrigin: true.secure: false.// pathRewrite pathRewrite.
          pathRewrite: {
            '^/api': ' '
          },
          headers: {
            Referer: target
          }
        },
      ],
    }
}
Copy the code

Minminchan-glitch.com any path addresses containing/API that are accessed on local port 8088 will be proxy to minchan-glitch.com using webPack-dev-server

The last

The text summarizes seven cross-domain solutions that I hope will help you. If you think there is something wrong with the article, please criticize and support it.

Thank you for watching this article hope to give a 👍 comment collection three even! Your likes are my motivation to write.