This article is written by Tuque community member Canruo starry sky, welcome to join tuque community, create wonderful free technical tutorials together, to force the development of programming industry.

If you think we have done a good job, please remember to like + follow + comment 🥰🥰🥰 and encourage us to write a better tutorial 💪

An introduction to

Js, React. Js, and Angular.js are becoming more and more powerful. More and more developers are moving from the traditional MVC architecture to building their own systems based on the infrastructure of front end separation. Deploy front-end and back-end services under different domain names. In this process, an important problem is the problem of cross-domain resource access. Usually, because the homodomain security policy browser will intercept the cross-domain network request of JavaScript script, it also causes the problem that the front-end cannot access the back-end resources when the system goes online. The author will combine with their own development experience, the cause of this problem and the corresponding solution, give a detailed introduction.

Question why

The same-origin policy

The same origin policy, which is a famous security policy proposed by Netscape. This strategy is now used by all browsers that support JavaScript. The same protocol, domain name, and port are the same.

Here’s an example:

When a script is executed on the Baidu TAB page of the browser, the system checks which page the script belongs to, that is, check whether the script is of the same origin. Only the script with the same origin as Baidu is 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.

The phenomenon of analysis

During the front-end development phase, some scaffolding tools for the framework will use Webpack-dev-serve to broker data requests, which is essentially a Node.js-based web server so that cross-domain resource access is not felt.

When the website is launched, many resources on the web page are required to request resources from the server through AJAX requests. However, in the system architecture with the front-end and back-end separated, front-end pages and back-end services are often not deployed under the same domain name. For example, the user visits www.test001.com through the browser and goes to the home page of the system. At this time, the browser only gets back the basic HTML page, CSS style sheet files and JavaScript scripts from the website server. Other contents of the system home page, such as the rotation chart and article list, need to use JavaScript scripts to send requests to the back-end application server at www.test002.com to obtain information. In this case, the request is blocked by the browser because of the same origin policy. As a result, data on the front and back ends cannot be accessed.

The solution

Front-end solutions

The reverse proxy

Because of the browser’s same-origin policy, a JavaScript script can only send a network request to a server under the same domain name, so the web server can forward the network request to the corresponding back-end server, get the relevant data, and the web server can return this data to the browser. This process is called reverse proxy.

Assume that the user through the homepage address www.test001.com access to the system, the system is in the home page to load JavaScript steps program should have to send an AJAX request to the www.test002.com/api/article… This address, to get the first page article list information. Should change to www.test001.com/api/article at this time… This cognate address sends the data request. The system of the web server receives the request, and then replace the JavaScript script to www.test002.com/api/article… This address requests data, retrieves it and returns it to the browser. At this point, the JavaScript script successfully fetches data from the back-end application server through the bridge of the web server.

If the server uses the pagoda panel management software, you can directly set the reverse proxy on the visualized interface. For some novice, directly facing the command line for various operations, not intuitive and difficult, at this time the use of some visual server management software is a good choice.

This blog is for those of you who prefer to use Vim to modify directly from the command line

Does this solution look familiar?

The json cross-domain

The same origin policy of the browser restricts the JavaScript script to request data from servers in different domains, but does not restrict the <script> tags in HTML. Based on this rule, we can dynamically create <script> tags for cross-domain resource access. The SRC attribute in the <script> tag is set to the address of the interface + the name of the callback function that handles the data. Examples of related code are as follows:

<script> var script = document.createElement('script'); script.type = 'text/javascript'; / / set the interface address + data to obtain the success of the callback function (the handleData) script. SRC = 'http://www.test002.com/api/articleList&callback=handleData'; document.body.appendChild(script); Function handleData(res) {data = json.stringify (res) console.log(data); } </script>Copy the code

It is important to note that the interface address of the request data is written in the SRC attribute value of the <script> tag, so the data request mode can only support GET requests, other requests cannot be implemented. JSONP’s cross-domain approach is not a good choice for projects based on a framework such as vue.js, which uses the concept of virtualized DOM. For native JavaScript code, it can be cross-domain in this way.

Back-end solutions

Cross-domain resource sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to allow Web applications running on one Origin (domain) to access specified resources from different source servers.

For security reasons, browsers restrict cross-source HTTP requests from within scripts. For example, the XMLHttpRequest and Fetch apis follow the same origin policy. This means that Web applications using these apis can only request HTTP resources from the same domain that loaded the application, unless the response message contains the correct CORS response header! Therefore, in order to achieve cross-domain resource access, it is required that the backend server should configure the corresponding HTTP response headers according to the CORS policy.

Access-Control-Allow-Origin: *
Copy the code

Indicates that the resource can be accessed by any external domain.

If the server only allows access from test001.com, the header field would look like this:

Access-Control-Allow-Origin: http://test001.com 
Copy the code

Express

In Node.js’s lightweight Web framework Express, we simply install a CORS library and add this middleware to configure cross-domain problems:

npm install cors
Copy the code

Then use this middleware in Express applications:

var express = require('express')
var cors = require('cors')
var app = express()
 
app.use(cors())
 
app.get('/products/:id'.function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins! '})
})
 
app.listen(80.function () {
  console.log('CORS-enabled web server listening on port 80')})Copy the code

In this way, all domain name request methods are allowed. For more cross-domain control for individual routes, see the CORS documentation.

SpringBoot

A configuration class can be added to springboot-based applications for CORS configuration. The specific code is as follows:

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
    @Autowired
    AdminInterceptor adminInterceptor;
    // Configure cross-domain correlation
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/ * *")
                .allowedMethods("*")
                .allowedOrigins("*")
                .allowedHeaders("*");
        super.addCorsMappings(registry); }}Copy the code

The code above is a crude solution that allows all request methods for all domain names. In the actual development process, the request path, request method, source and request header of the received request should be restricted to ensure the security of the service. Continuing with the example above, the security configuration should look like this:

    // Configure cross-domain correlation
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedMethods("GET")
                .allowedOrigins("www.test001.com")
                .allowedHeaders("*");
        super.addCorsMappings(registry);
    }
Copy the code

In this configuration, only the domain www.test001.com can access the server data, and only GET data requests are accepted. The access path is restricted, and only the path starting with/API can be accessed. This further ensures the security of back-end applications.

Flask

In an application service developed based on Flask, a lightweight Web services framework, the Flask cross-domain resource shared libraries are first installed using the PIP install Flask_cors command. The following code can be used to configure CORS.

from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
Copy the code

conclusion

Cross-domain problems are common in the current architecture of back-end separation. Although these solutions introduced in this paper can solve cross-domain problems, they have their own advantages and disadvantages. For example, Jsonp mode is relatively simple to implement, but only supports GET request mode. It is convenient to use in native JavaScript scripts, but it is difficult to put into practice when using MVVM framework such as vue.js. The reverse proxy method does not need to change the back-end code, but has poor portability for the whole system. CORS method requires the back-end to actively cooperate with the front-end to achieve cross-domain. In short, there is no technical silver bullet, we need to compare and analyze the actual situation, choose the most appropriate plan.

If you think we have done a good job, please remember to like + follow + comment 🥰🥰🥰 and encourage us to write a better tutorial 💪

Want to learn more exciting practical skills tutorial? Come and visit the Tooquine community.