百度智能云

All Product Document

          Object Storage

          How to Solve CORS Problems of a Browser

          Introduction

          Same-origin Policy

          The same-origin policy is a famous security policy applied to browser by Netscape in 1995.It is the most core and basic security function of browser. It can be summarized that scripts in this origin can only read and write resources in this origin, but cannot access resources in other origins to prevent information leakage. For example, Website A and Website B belong to two different origins (for example, www.a.com and www.b.com). JavaScript in Website A can only access the resources of Website A, but not the resources of Website B, for the restriction of the same-origin policy makes cross origin access rejected by the browser.

          The same-origin refers to the same origin name, the same protocol and the same port. For example:

          • Different origin names: http://www.baidu.com and http://www.baidu.cn are different origins;
          • Different protocols: http://www.baidu.com and https://www.baidu.com are different origins;
          • Different ports: http://www.baidu.com:80 and http://www.baidu.com:81 are different origins;
          • Other: http://www.baidu.com/a and http://www.baidu.com/b are the same origin, for the origin name, protocol and port are the same.

          What Is Cross-origin Resource Sharing (CORS)

          In practical applications, cross-origin access is often encountered. For example, the user's Website A (www.a.com) uses BOS storage at the back end. If the user wants to refer to the resources stored on BOS in the web application of the website, but the page can only request the resources of the origin, so the requests sent to BOS will be limited by the browser, and the failure in direct access will make it inconvenient. In order to solve this kind of cross-origin access problem, HTML5 provides a set of standard cross-origin solution, that is, CORS.

          Cross-Origin Resource Sharing (CORS) is a set of control policies followed by browsers. It interacts through HTTP Header. When the browser recognizes that the initiated request is a cross-origin request, it will add the Origin Header to the HTTP request and send it to the server. In the above example, the Origin Header is www.a.com. After receiving the request, the server will judge whether to allow the request of the source origin according to certain rules. If allowed, the server will attach the Header of Access-Control-Allow-Origin, with the content of www.a.com to indicate that cross-origin access is allowed. If the server allows all cross-origin requests, set the Header of Access-Control-Allow-Origin to *. The browser determines whether the cross-origin request is successful according to whether the corresponding Header is returned. If no corresponding Header is attached, the browser will intercept the request.

          CORS shall be supported by browser and server at the same time. The whole communication process of CORS is completed automatically by browser without the participation of users. Once the browser finds that AJAX request cross-origins, it will automatically add some additional header information, and sometimes there will be an additional request. As long as the server implements the CORS interface, it can achieve across-origin communication.

          The browser divides CORS requests into two categories: Simple request and not-so-simple request.

          Simple request means that the request mode is one of the three modes of HEAD/GET/POST, and the http header information does not exceed the following fields:

          • Accept
          • Accept-Language
          • Content-Language
          • Last-Event-ID
          • Content-Type: It is limited only to three values: application/x-www-form-urlencoded, multipart/form-data, text/plain

          Those failing to meet the above conditions are not-so-simple requests. For not-so-simple CORS requests, a HTTP OPTIONS query request will be added before formal communication, which is called "Pre-check" request. The request header information includes three special fields: Origin, Access-Control-Request-Method and Access-Control-Request-Headers. After receiving the "Pre-check" request, and checking the three fields, the server confirms to allow the cross-origin request, and makes a reply. The server's response will have an Access-Control-Allow-Origin header field.

          BOS Configuration CORS

          BOS provides developers with two ways to configure cross-origin access rights of bucket resources. One is to directly set CORS rules for bucket in BOS console. The other is to recall CORS-related API interfaces to control access to bucket resources.

          Note:

          • CORS configuration in BOS is at bucket level;
          • Whether a CORS request passes or not is completely independent of the BOS authentication, because the CORS rule is only a rule used to determine whether to attach a CORS-related Header, and whether to intercept the request is entirely up to the browser.
          • Setting through the console:

            1.Click the "Basic Configuration" tab, select "cross-origin Access CORS Settings" and click "Modify Configuration".

            2.Click "OK" to save the rule.

            image.png

          • API control method:

            1. PutbucketCors Interface: used to set a cross-origin resource sharing (CORS) rule on the specified bucket, and overwrite the original rule if it exists.
            2. GetbucketCors Interface: to get the current CORS rule for the specified bucket.
            3. DeleteBucketCors Interface: used to turn off the CORS function of the specified bucket and clear all rules.
            4. OPTIONS Objec Interface: before sending a cross-origin request, the browser will send a preflight request (OPTIONS) with specific source origin, HTTP method and Header information, etc. to BOS to decide whether to send the real request. This interface responds to such request.

          Practical Case

          We will show in detail the cross-origin access of simple and not-so-simple requests to BOS resources. The simple request takes GET request as an example, and the not-so-simple request takes POST request as an example.

          Preparation Conditions

          1.Log in to the BOS console to create a new bucket, set the read-write permission to "Public Read-Write", and upload an object. In this example, we create a new bucket named bos-demo and upload a bos.txt file with the content of "this is a bos demo for CORS test !". Click "Copy Link", and you can see the access address of bos.txt object:<http://bos-demo.bj.bcebos.com/bos.txt. > 2.Disable the browser cache function to prevent mismatch with the requirements of CORS, for the browser has cached the header content returned by the server last time, which affects the request result. Here, take chrome browser as an example, open "Developer tools" and check "Disable cache".

          Cross-origin Request Instance

          1.First, access bos.txt file by curl, and you can find that the object can be accessed normally.

          curl http://bos-demo.bj.bcebos.com/bos.txt  
          This is a bos demo for CORS test ! 

          2.Then, we try to use Fetch API to access the object. You can copy the following code to the local file and save it as html file and open it with a browser. The code provides the functions to send GET and POST requests.

          <!DOCTYPE html>   
          <html>  
          <body>  
            <p align="center" style="font-size: 30px;">  
              <button onclick="sendGetCorsRequest()">Send Get Request</button>  
              <button onclick="sendPostCorsRequest()">Send Post Request</button>  
            </p>  
            
            <script type="text/javascript">  
              var url = "http://bos-demo.bj.bcebos.com/bos.txt";  
            
              function sendGetCorsRequest() {  
                fetch(url).then(function(res) {  
                  if (res.ok) {  
                    alert("The response is ok, get request success!"); 
                  } else {  
                    alert("The response wasn't ok, got status ", res.status);  
                  }  
                }, function(e) {  
                  alert("Get request failed!", e);  
                });  
              }  
            
            function sendPostCorsRequest() {  
              fetch(url, { method: "POST" }).then(function(res) {  
                  if (res.ok) {  
                    alert("The response is ok, post request success!");  
                  } else {  
                    alert("The response wasn't ok, got status ", res.status);  
                  }  
                }, function(e) {  
                  alert("Post request failed!", e);  
                });  
              }  
            </script>  
          </body>  
          </html>

          After opening the html file (take Chrome for example), click "Send Get Request" or "Send Post Request", and you will find that both requests failed to be sent.

          By reading the error prompt in the chrome Console, we can see that the Access-Control-Allow-Origin header was not found. Obviously, this is because the server is not configured with CORS.

          Enter Header interface again, and you can see that the browser sent a Request with Origin, so it is a cross-origin request. In Chrome, Origin is empty because it is an open local file.

          Rules for Bucket CORS Configuration

          CORS settings are made up of one rule after another. The real matching will be started from the first rule one by one, and the earliest matched one will prevail. Now add the first rule, and use the most relaxed configuration:

          image.png

          The configuration in the figure above represents that all access to all Origins are allowed, all access to request types are allowed, all Headers are allowed, and the maximum cache time is 10s. For specific parameter meanings, please see the BOS product configuration document. Retest after configuration is complete, and the results are as follows:

          Get request result:

          Post request result:

          You can find that POST and GET requests can be sent successfully after we configure the CORS rules. In addition to the loosest configuration, you can also configure more sophisticated control mechanisms to achieve targeted control. For example, for a bucket, only get requests are allowed, but no other requests are allowed, or only a origin name is allowed to access the bucket. These can be configured in the console. For most scenarios, it is better for users to use the minimum configuration according to their own usage scenarios to ensure security.

          Note:

          CORS configuration items have the following precautions:

          • Origins: The configuration shall be provided with the complete origin information. Do not omit the protocol name, such as html. If the port number is not the default, the port number shall be provided. If you are not sure, open the debugging function of the browser to view the Origin header. This supports the use of wildcard *, but only one, which can be flexibly configured according to actual needs.
          • Methods: Enable the corresponding method as demanded.
          • Headers: Allow the list of headers to pass. This recommendation is set to *, case insensitive, if no special requirements are needed.
          • ExposeHeader: For List of headers exposed to the browser, wildcards are not allowed. The specific configuration shall be selected according to the application requirements, and only the Headers shall be used, such as ETag, are exposed. If you don't need to expose this information, leave it blank here. In case of special requirements, they can be specified separately, and the case is not sensitive.
          Previous
          Mobile Meitu APP Practice
          Next
          HTTPS Transmission Encryption Practice