Part ONE: Front and back end interaction and HTTP

1. Communication between the front and rear ends

1.1 What is Front-end and Back-end Communication?

Front-end and back-end communication refers to the process of data exchange (request-response) between the browser and server: the front-end sends the request data to the back-end, and the back-end responds to the data request after receiving the request from the front-end

  • Front-end and back-end send data (user registration) : the browser submits user registration information in the form of a form, click registration and then send it to the server for processing
  • Back end sends data to the front end (accessing the page): after the user enters the URL and presses Enter, requests some resources to load, and the back end returns the server’s resources for the browser to render

1.2 Front – and Back-end Communication Modes (three)

1. Use a browser to access the page for communication

Enter the url in your browser’s address bar and press Enter

2.HTML tags for communication

When parsing HTML tags, the browser encounters some special tags (link/img/script/iframe) and sends a request to the server again. Chrom allows up to six concurrent requests for the same domain, so put resources in different domains to increase efficiency.

There are also tags that the browser does not send requests to the server when it parses, but the user can use them to send requests to the server such as a/form

3. Ajax and Fetch

2. The HTTP protocol

2.1 What is HTTP?

  • HyperText Transfer Protocol (HyperText Transfer Protocol
  • Hypertext: Originally a single piece of text, connected by hyperlinks. From the original single text into infinite extension, expansion of hypertext, three-dimensional text
  • HTML, JS, CSS, images, fonts, audio, video, and so on are all transferred between the server and the browser over HTTP (Hypertext Transfer Protocol)
  • Each time the front end communicates with the back end, the front end sends a request to the back end. After receiving the request, the back end can give a response

2.2 HTTP Browser Rendering Process (Diagram)

2.3 HTTP message

  • When the browser sends a request to the server, the request itself is information, calledThe request message;
  • The information that the server transmits in response to the browser is calledThe response message;

HTTP Packet Format Request Header: start line + head request body// GET request, no request body, data is carried through the request header
      // A POST request has a request body, through which data is carriedResponse Response header: start line + header response bodyCopy the code

2.4 Common HTTP Methods (Add, Delete, Modify, And Query)

HTTP methods that define what to do with a resource have their own semantics, and the way that the browser sends the request has nothing to do with the response. Okay

  • 1.GET Obtains data

    • GET carries data in the request header by address
    • The amount of data that can be carried depends on the length of the address, usually only a few K at most
    • GET sends data through the request header, the URL, and can be cached
    • Unsafe url? username=alexThe GET data is in the URL, and the cache can easily find the data through the history.
    • GET harmless: Refresh, back, and other browser actions to GET requests are harmless,
  • 2.POST create data (register)

    Submit data to a specified resource for processing requests (such as submitting a form or uploading a file). The data is contained in the request body. POST requests may result in the creation of new resources and/or the modification of existing resources.

    • A POST can carry data either in the request header via an address or in the request body
    • The amount of data that can be carried is theoretically unlimited
    • POST typically sends data through the request body, so it is not cached
    • POST data is secure because it is not cached in the request body
    • POST may submit the form repeatedly
  • 3.PUT Update data (modify personal information, change password)

    Data transferred from the client to the server replaces the contents of the specified document. Such as updating an article

  • 4.DELETE DELETE data (DELETE a comment)

    Asks the server to delete the specified page.

  • RESTful interface design

An interface design style that takes full advantage of the semantics of HTTP methods, such as setting up the user interface, adding, deleting, changing and checking the interface are the same, but the backend can determine your corresponding operation according to your request mode

2.5 Common HTTP Status Codes

The HTTP status code defines the server’s processing of the request and is returned by the server.

  • 100-199 message: indicates that the request has been accepted and needs to continue processing // webSocket
  • The client must continue to make requests
  • 101 The client requests the server to convert the HTTP protocol version upon request
  • From 200 to 299
  • 200 (Success) The server has successfully processed the request. Typically, this means that the server has provided the requested web page.
  • 201 (Created) The request succeeded and the server created a new resource.
  • 202 (Accepted) The server has accepted the request but has not yet processed it.
  • 300~399 Redirection: gives you a new request address, you need to resend the request with the new address
  • 301 Moved Permanently
  • 302 Move Temporarily The server currently responds to a request from a web page at a different location, but the requester should continue to use the original location for future requests.
  • You may continue to use it.
  • 400 to 499 The request is incorrect
  • 400 (Error request) Server does not understand the syntax of the request.
  • The 401 (unauthorized) request requires authentication. The server may return this response for a web page that requires login.
  • 403 (Forbidden) The server rejects the request.
  • 404 Not Found
  • 500~599 Server error (server error)
  • 500 Internal Server Error

Part two: Local storage

1.Cookie

  • Cookie (HTTP Cookie) is a way for the browser to store data on the user’s local PC. Generally, the data is automatically sent to the server with each browser request
  • Cookies are used to track the habits of users to visit the website, such as when to visit, which pages are visited, and how long they stay on each page
  • Do not save sensitive information such as passwords in cookies.

2. Basic usage of cookies (set and read in code)

2.1. Write cookies (cannot be set together, only one by one)

       document.cookie = 'username=zs';
       document.cookie = 'age=18';
Copy the code

2.2. Read the cookies

It reads a string of name-value pairs, each separated by a “;” Separate (a semicolon and a space)

      console.log(document.cookie);
      // username=zs; age=18
Copy the code

3. The attribute of the Cookie

3.1 Name and Value of Cookie

  • The two most important attributes must be filled in when creating cookies, and the other attributes can use default values
  • If the name or value of Cookie contains non-English letters, encodeURIComponent() should be used when writing, and decodeURIComponent() should be used when reading
      document.cookie = `username=The ${encodeURIComponent('Joe')}`;
      document.cookie = `The ${encodeURIComponent('Username')}=The ${encodeURIComponent(
        'Joe'
      )}`;
Copy the code

3.2 Expiry (Expiration) time

  • Invalid cookies are cleared by the browser
  • If no expiry (expiration) time is set, such a Cookie is called a session Cookie. It exists in memory and disappears when the session ends, that is, when the browser closes
  • To last a long time, set Expires or max-age
// Expires property, which is of type Date
      document.cookie = `username=alex; expires=The ${new Date(
        '2100-1-01 00:00:00'
     )}`;
 // max-age The value is a number, indicating the current time plus the number of seconds after the expiration, in seconds
 // If max-age is 0 or negative, the Cookie is deleted
      document.cookie = 'username=alex; max-age=5';
      document.cookie = `username=alex; max-age=The ${24 * 3600 * 30}`;
Copy the code

3.3 Domain Domain

Domain specifies the scope of Cookie access (different Domain names). If you use JS, you can only read and write cookies of the current Domain or the parent Domain, but cannot read and write cookies of other domains

       document.cookie = 'username=alex; domain=www.imooc.com';
Copy the code

3.4 the Path Path

Path limits the scope of access to cookies (under the same domain name). If you use JS, you can only read and write cookies of the current Path and upper-level Path, but cannot read and write cookies of lower-level paths

       document.cookie = 'username=alex; path=/course/list';
       document.cookie = 'username=alex; path=/1.Cookie/';

      // If the Name, Domain, and Path fields are the same, the Cookie is the same
Copy the code

3.5 HttpOnly

Cookies with an HttpOnly attribute cannot be accessed through JS

3.6 Secure Flag

Secure specifies that the server can be sent only when HTTPS is used instead of HTTP. Domain, Path, Secure, and cookies that cannot expire can be sent to the server along with the request

4. Encapsulation of cookies

Encapsulate a cookie in cookie.js and provide three methods: set, get and remove

 // import { set, get, remove } from './cookie.js'; Cookie methods are introduced elsewhere
// 1. Write a Cookie:
const set = (name, value, { maxAge, domain, path, secure } = {}) = > {
  let cookieText = `The ${encodeURIComponent(name)}=The ${encodeURIComponent(value)}`;

  if (typeof maxAge === "number") {
    cookieText += `; max-age=${maxAge}`;
  }

  if (domain) {
    cookieText += `; domain=${domain}`;
  }

  if (path) {
    cookieText += `; path=${path}`;
  }

  if (secure) {
    cookieText += `; secure`;
  }

  document.cookie = cookieText;

  // document.cookie='username=alex; max-age=5; domain='
};

// 2. The get method gets the value of the cookie by name
const get = (name) = > {
  name = `The ${encodeURIComponent(name)}`;

  const cookies = document.cookie.split("; ");

  for (const item of cookies) {
    const [cookieName, cookieValue] = item.split("=");

    if (cookieName === name) {
      return decodeURIComponent(cookieValue); }}return;
};
// get(' username '); To obtain

The remove method removes cookies based on name, domain, and path
const remove = (name, { domain, path } = {}) = > {
  set(name, "", { domain, path, maxAge: -1 });
};

export { set, get, remove };
Copy the code

Use cookie.js in other files

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Cookie encapsulation</title>
  </head>
  <body>
    <script type="module">
      import { set, get, remove } from './cookie.js';
// Set the cookie name value
       set('age'.18);
       set('Username'.'Joe');
       set('sex'.'male', {
         maxAge: 30 * 24 * 3600
       });
       
/ / get a cookie
       get('sex');
       
/ / delete the cookie
       remove('username');
       remove('Username');
    </script>
  </body>
</html>
Copy the code

5. localStorage

  • LocalStorage is also a way for the browser to store data (localStorage). It is stored locally and not sent to the server.
  • A persistent storage mode, meaning that data will never expire unless it is manually cleaned up. It uses key-value pair to store data and saves the data to the corresponding database file according to the domain name. It can hold much more data than a Cookie.
  • SessionStorage is a session-level cache that is cleared when the browser is closed. Note that the scope of sessionStorage is window level, that is, sessionStorage data stored between different Windows cannot be shared. SessionStorage data only exists in the current browser TAB;

LocalStorage features:

The size is limited to 5MB to 10MB. Sharing data between all tabs and Windows of the same origin; Data is only stored in the client and does not communicate with the server. Data persists and does not expire. The data persists after the browser is restarted. Operations on data are synchronous.

5.1 localStorage Method:
// Add a data item with setItem()
localStorage.setItem('myName'.'Semlinker');

// Get an item from getItem()
// Get nonexistent returns null
let me = localStorage.getItem('myName');

// Remove an item by removeItem()
// Delete a nonexistent key
localStorage.removeItem('myName');

// Remove all data items
localStorage.clear();
Copy the code
5.1 Key Values of localStorage:

The keys and values stored in localStorage can only be strings. If they are not strings, they will be converted to strings before being saved

Part three: Ajax basics

1. What is Ajax?

Ajax is short for Asynchronous JavaScript and XML.

  • Asynchrony in Ajax: You can send requests asynchronously to the server without blocking the current page while waiting for a response, and the browser can do its own thing. The browser does not process the response data until the response is successfully retrieved
  • XML (Extensible Markup Language) is a format for transmitting data in front and back end data communication. XML is not used much now. JSON is more commonly used now
  • Ajax is simply an asynchronous communication between the browser and the server
  • Using Ajax, you can update parts of a page without reloading the entire page

Example ① MoOCs registration test; ② MoOCs search tips

2. Build an Ajax development environment

Ajax requires a server environment, and many browsers cannot use Ajax properly in a non-server environment. Install Live Server plug-in in vscode to quickly set up the Server environment

3. How to use Ajax

Ajax, for asynchronous communication between the browser and the server, relies on XMLHttpRequest, which is a constructor. The core four steps for sending an Ajax request:

  • 1. Create an XMLHttpRequest instance object.
  • 2. Open the request connection and configure the request information.
  • 3. Listen for request statuses – Different statuses do different things.
  • 4. Send the AJAX request and the AJAX task begins until the response body message returns indicating the end of the task.

3.1. Create an XMLHttpRequest instance object

       const xhr = new XMLHttpRequest();
Copy the code

3.2. Open the request connection and configure the request information

Calling open does not actually send the request, but merely prepares the request to be sent

xhr.open('GET'.'url'.trueThe first parameter is HTTP request mode: GET, POST, PUT, DELETE. The second parameter is the request address. The third parameter is whether the request is asynchronous.trueIndicates an asynchronous requestCopy the code

3.3. Listen for events and process responses

When the response is received (readyState changes), the XHR object’s ReadyStatechange event is triggered, in which the response can be processed to determine whether the request status is complete and whether the request was successful

AJAX status code — xhr.readyState HTTP status code — xhr.status The readyStatechange event listens for changes in the readyState state, which ranges from 0 to 4.

0: not initialized. Open () has not been called1: start. Open () has been called, but send() has not been called2: sending. Send () has been called, but no response has been received3: to receive. Partial response data has been received4: complete. All response data has been received and is ready for use in the browserCopy the code
      xhr.onreadystatechange = () = > {
      // 4: done. All response data has been received and is ready for use in the browser
        if(xhr.readyState ! = =4) return;
        
      //200-299: yes, the request was received and processed successfully.
      //304: Not Modified. When this status code is returned, it does not return any resources, but instead tells the browser to fetch the resources in the cache.
        if ((xhr.status >= 200) & (xhr.status < 300) || xhr.status === 304) {
          // console.log(' Normal use response data ');
          console.log(xhr.responseText); }};Copy the code

Or:

       xhr.addEventListener('readystatechange'.() = >{... }, fasle);Copy the code
  • For compatibility, this is not used in readyStatechange, but XHR is used directly
  • For compatibility reasons, it is best placed before Open

3.4. Send the request

// Send () is the data carried by the request body, so the send method of GET does not take arguments or null
xhr.send(null);
Copy the code

4. Use Ajax to complete the front and back end communication – small case

      const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

      const xhr = new XMLHttpRequest();
      xhr.onreadystatechange = () = > {
        if(xhr.readyState ! = =4) return;

        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
          console.log(xhr.responseText);
          console.log(typeof xhr.responseText);
         / / XMLHttpRequest. The responseText, after a request is sent from the server side back to the text.}}; xhr.open('GET', url, true);
      xhr.send(null);
Copy the code

5. Ajax GET requests

1.GET requests cannot carry data through the request body, but can carry data through the request headerconst url =
        'https://www.imooc.com/api/http/search/suggest?words=js&username=alex&age=18';

2.Data encoding If the data carried is not English letters, such as Chinese characters, it needs to be encoded and then sent to the back end, otherwise it will cause garbled characters problem can be usedencodeURIComponent() codeconst url = `https://www.imooc.com/api/http/search/suggest?words=The ${encodeURIComponent(
        'front end'
      )}`;
Copy the code

Ajax POST requests

1.POST requests carry data mainly in the request body, but also in the request header. If you want to send data, you write it directly to the parameter of send(), usually in the string xhr.send().'username=alex&age=18'); Xhr.send ({xhr.send({xhr.send));username: 'alex'.age: 18
      });
Copy the code

7.JSON

JSON is a format that Ajax uses to send and receive data. JSON comes in three forms, each of which is written like a JS data type and can be easily converted to and from a JS data type

7.1 Three JSON forms

  • 1. Simple value formxxx.json

The simple value form of JSON corresponds to the basic data types in JS: numbers, strings, Booleans, and NULL

Note ① There is no undefined value in the JSON. ② Strings in the JSON must use double quotation marksCopy the code
  • 2. Object form

JSON objects correspond to objects in JS

Note: The property name of the OBJECT in JSON must be quoted in double quotes, and the value of the property must be quoted in double quotes if the property value is a string in JSON, the property name must be quoted in double quotes whenever the string is involved. Undefined is not supportedCopy the code
  • 3. Array format

JSON arrays correspond to arrays in JS

[1, "hi", NULL] Note: Strings in an array must be quoted in double quotes. In JSON, strings must be quoted in double quotes. Undefined is not supportedCopy the code

7.2 Two Basic Uses of JSON

1. Json.parse () can parse JSON-formatted strings into JS values

It must be a valid JSON string, otherwise an error will be reported

2. Json.stringify () converts basic JS data types, objects, or arrays to jSON-formatted strings

     xhr.send(JSON.stringify({
         username: 'alex'.age: 18
       }))
Copy the code

7.3 Encapsulating localStorage using JSON

The key and value in localStorage are strings, but sometimes we want to pass some array objects, we can encapsulate them:

const storage = window.localStorage;
/ / set
const set = (key, value) = > {
  / / {
  // username: 'alex'
  // }
  storage.setItem(key, JSON.stringify(value));
};

/ / to get
const get = key= > {
  // 'alex'
  / / {
  // "username": "alex"
  // }
  return JSON.parse(storage.getItem(key));
};

/ / delete
const remove = key= > {
  storage.removeItem(key);
};

/ / to empty
const clear = () = > {
  storage.clear();
};

export { set, get, remove, clear };
Copy the code

The fourth part is cross-domain

  • Cross domainIt’s sending requests between different domains;
  • Different domainsIf the protocol, domain name, and port number are different, they are different domains.
  • The same-origin policyIs a security policy of the browser that prevents cross-domain requests.

Cross-domain solution: ① CORS cross-domain resource sharing ② JSONP Preferentially uses CORS cross-domain resource sharing. If the browser does not support CORS, use JSONP

1. The first cross-domain solution: CORS cross-domain resource sharing (IE10 for the backend)

Access-control-allow-origin: access-control-allow-origin: access-control-allow-origin: http://127.0.0.1:5500 // Only cross-domain requests of the specified domain name are allowed. CORS Cross-domain process ① The browser sends a request ② the back end adds the Access-Control-Allow-Origin header to the response header ③ The browser receives the response ④ If is the same under the domain of the request, the browser will not do, extra before and after the end of the communication is accomplished (5) if the cross-domain request, the browser will look for whether to allow cross-domain access from the response headers 6. If allowed to cross domain, the successful completion of the communication all landowners if not found or does not contain want cross-domain domain, discarding the response resultCopy the code

2. The second cross-domain scheme: Jsonp

The principle of JSONP: Script tags across domains are not blocked by browsers. JSONP mainly uses script tags to load cross-domain files.

Cross-domain implementation using JSONP:

1. The back-end to create an interface, pay attention to the aaaa is behind the front literally defined: ` ` 2 at https://www.imooc.com/api/http/jsonp?callback=aaaa. Aaaa ({"code": 200, "data": [{"word": "JSP"}, {"word": "js"}, {"word": "js"}, {"word": "js"} : "Json"}, {" word ":" introduction to js "}, {" word ":" JSTL "}}); 3. The front end simply introduces the interface in the script tag, and then declares an aAAA function based on the callback=aaaa we define in the interface 4. This function is called when the request is sent, passing the data through the function callCopy the code
/ * ready to json on the server interface: https://www.imooc.com/api/http/jsonp?callback=handleResponse * /
/* The front end loads the JSONP interface manually or dynamically */
  const script = document.createElement('script');
  script.src ='https://www.imooc.com/api/http/jsonp?callback=handleResponse';
  document.body.appendChild(script);

// Declare the function
      const handleResponse = data= > {
        console.log(data);// Get the data
      };
// It is equivalent to passing arguments to the function through the execution of the function
Copy the code

Part five: XMLHttpRequest objects

1. The XMLHttpRequest properties

ResponseType: indicates the text of the response:

  • ResponseType is set before it is ready to send and send
  • If responseType is not set, then responseText is the same as responsexhr.responseType='text';
  • When you set responseType to JSON, you need to get the response property;
  • If you know the format returned by the backend is JSON, you do not need to compile it. The system will compile it automatically.

2. Timeout property: Set the timeout time of the request (unit: ms) xhr.timeout = 10000; 3. The withCredentials property: Specifies whether cookies are carried when Ajax requests are sent

Sending requests using Ajax, by default, carries cookies when in the same domain; Xhr. withCredentials = true is not allowed across domains; Ultimately, the success of cross-domain Cookie portability depends on whether the server agrees or not

2. The method of XMLHttpRequest

1.Abort () Terminates the current request. This is usually used in conjunction with the ABORT event2.SetRequestHeader () sets the request header information. Xhr.setrequestheader (the name of the header field, the value of the header field) is only necessary to send a POST request. xhr.setRequestHeader('Content-Type'.'application/json');
      // The content-Type field in the request header tells the server what format the browser sent the data in
     
     1.Send JSON data xhr.setrequesTheader ('Content-Type'.'application/json');// The browser sends json data
      xhr.send(
        JSON.stringify({
          username: 'alex'}));2.Send name value pair data xhr.setrequesTheader ('Content-Type'.'application/x-www-form-urlencoded');
      xhr.send('username=alex&age=18');

// If this fails, let the back end change the interface
Copy the code

3. The XMLHttpRequest events

3.1. Load event – Triggered when response data is available

The load event can replace the xhr.onReadyStatechange event by listening only for the success of the response (xhr.status) and not for the success of the request (readyState).

xhr.addEventListener(
        'load'.() = > {
          if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
            console.log(xhr.response); }},false
      );
// Ie6-8 is not supported
Copy the code

3.2. Error event – Triggered when an error occurs in a request (such as an address error, the request was not sent at all)

xhr.addEventListener(
        'error'.() = > {
          console.log('error');
        },
        false
      );
Copy the code

3.3. Abort event – Triggered when calling ABORT () to terminate the request (IE10 +)

3.4. Timeout event – Triggered after the request times out (IE8 +)

Part six: Ajax advancements

1.FormData

When submitting a form using Ajax, we use FormData; Basic usage of FormData:

// Create a FormData object from an HTML form element
      const fd = newFormData(form element); xhr.send(fd);// Add data through the append() method
      const fd = newFormData(form element); fd.append('age'.18);
      fd.append('sex'.'male'); xhr.send(fd); Internet Explorer 10 and later are supportedCopy the code
<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>FormData</title>
  </head>
  <body>
    <form
      id="login"
      action="https://www.imooc.com/api/http/search/suggest?words=js"
      method="POST"
      enctype="multipart/form-data"
    >
      <input type="text" name="username" placeholder="Username" />
      <input type="password" name="password" placeholder="Password" />
      <input id="submit" type="submit" value="Login" />
    </form>
    <script>
      const login = document.getElementById('login');
      const { username, password } = login;
      const btn = document.getElementById('submit');
      const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

      btn.addEventListener(
        'click'.e= > {
          // Prevent form auto-submission
          e.preventDefault();

          // Form data validation

          // Send an Ajax request
          const xhr = new XMLHttpRequest();

          xhr.addEventListener(
            'load'.() = > {
              if (
                (xhr.status >= 200 && xhr.status < 300) ||
                xhr.status === 304
              ) {
                console.log(xhr.response); }},false
          );
          xhr.open('POST', url, true);
          // Collect form data
          const data = new FormData(login);
                    console.log(data); // It can't be printed directly
                   for (item of data) {
                          console.log(item);
                        }
                   /* ["username", "1231"] ["password", "21313131"] */
          xhr.send(data);
        },
        false
      );
    </script>
  </body>
</html>
Copy the code

2. Ajax encapsulation

// Utility functions - turn objects into strings (serialization)
  Object.entries() object.entries () returns an array of key-value pairs for a given Object's own enumerable properties, arranged in the same way as for... The in loop returns the same order as it iterates through the object (the difference is that for-In also enumerates properties in the prototype chain) */
// Data is serialized into urlencoded strings
const serialize=param= >{
    const results=[];
    for(const [key,value] of Object.entries(param)){
        results.push(`The ${encodeURIComponent(key)}=The ${encodeURIComponent(value)}`)}//['username=alex','age=18']

The //join() method is used to put all the elements of an array into a string.
   return results.join("&")}Copy the code
Add parameters to the URL//www.muke.com
//www.muke.com?words=js
//www.muke.com?words=js&
const addURLData=(url,data) = >{
if(! data)return ' ';
const mark=url.includes('? ')?'&':'? '

return `${mark}${data}`
}

Copy the code

Step 1: Wrap: Ajax functions are wrapped in Ajax.js

// Step 1: Default parameter Settings:
const DEFAULTS = {
  method: "GET".// The data carried by the request header
  params: null.// params: {
  // username: "alex",
  // age: 14,
  / /},
  Username =alex&age=18

  // The data carried by the request body
  data: null.// data: {
  // username: "alex",
  // age: 14,
  / /},
  / / data: FormData data

  contentType: "application/x-www-form-urlencoded".responseType: "".timeoutTime: 0.withCredentials: false./ / methods:
  // The method of success
  success() {},
  // Status code exception processing
  httpCodeError() {},
  // There is an error, such as the address is not sent at all
  error() {},
  / / suspended
  abort() {},
  / / the overtime
  timeout(){}};// Step 2: Create an Ajax class
class Ajax {
  constructor(url, options) {
// The external url
    this.url = url;
// Default parameter Settings
    this.options = Object.assign({}, DEFAULTS, options);
    //1. Initialize, which is a tetralogy operation to make the code less crowded
    this.init();
  }
  init() {
    const xhr = new XMLHttpRequest();
    // Bind to a common property of the class
    this.xhr = xhr;

    //2. Write the listener method inside
    this.bindEvents();

    Xhr. open('POST', url, true);
    xhr.open(this.options.method, this.url + this.addParam(), true);
    / / 4. Set the responseType
    this.setResponseType();
    //5. Set whether to carry cookies across domains
    this.setCookie();
    //5. Set timeout
    this.timeout();
    Xhr.send ();
    this.sendData();
  }

  // Bind the area that responds to the event handler
  bindEvents() {
  / / lazy
    xhr = this.xhr;
    // Put the method structure inside the call
    const { success, httpCodeError, error, abort, timeout } = this.options;
    xhr.addEventListener(
      "load".() = > {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
          success(xhr.response, xhr);
        } else{ httpCodeError(xhr.status, xhr); }},false
    );
    
    // error
    // An error event is raised when the request encounters an error
    xhr.addEventListener(
      "error".() = > {
        error(xhr);
      },
      false
    );

    // abort
    xhr.addEventListener(
      "abort".() = > {
        abort(xhr);
      },
      false
    );

    // timeout
    xhr.addEventListener(
      "timeout".() = > {
        timeout(xhr);
      },
      false
    );
  }
// Below is the library of utility functions
  // Add data to the address, i.e. 'url? name=zs`
  /* Serialize ('username=alex&age=18'); AddURLData: unified data format plus & or ❓ */
  serialize(param) {
    const results = [];
    /* If it is an Object, make object. entries(param) a two-dimensional array and use for.. If it is an array, the */ is traversed directly
    for (const [key, value] of Object.entries(param)) {
      results.push(`The ${encodeURIComponent(key)}=The ${encodeURIComponent(value)}`);
    }
    ['username=alex','age=18']
    return results.join("&");
    Username =alex&age=18
  }
  addURLData = (url, data) = > {
    if(! data)return "";
    // If there is data add &, no data add?
    const mark = url.includes("?")?"&" : "?";

    return `${mark}${data}`;
  };
  // The above two utility functions are for him;
  addParam() {
  // Deconstruct the parameters
    const { params } = this.options;
    if(! params)return "";
    return addURLData(this.url, serialize(params));
  }

  / / set the responseType
  setResponseType() {
    this.xhr.responseType = this.options.responseType;
  }
  // Sets whether cookies are carried across domains
  setCookie() {
    if (this.options.withCredentials) this.xhr.withCredentials = true;
  }
  // Set timeout
  setTimeout() {
    const { timeoutTime } = this.options;
    if (timeoutTime > 0) this.xhr.timeout = timeoutTime;
  }
  // Send data
  sendData() {
    const xhr = this.xhr;
    // If you do not need to send data, send it directly
    if (!this.isSendData()) return xhr.send(null);

    Xhr.send (data)
    let resultData = null;
    
    //// Sends FormData data. Content-type does not need to be set and is automatically added
    if (this.isFormData()) {
      resultData = data;
      
     // // is not a name value pair :username=alex&age=18
    } else if (this.isFormURLEncodedData()) {
      / / set the contentType
      this.setContentType("application / x - www - form - urlencoded");
      // Send data in this format application/x-www-form-urlencoded
      resultData = this.serialize(data);
    } else if (this.isJsonData()) {
      / / set the contentType
      this.setContentType("application /json");
      resultData = this.serializeJson(data);
    } else {
      // Other formats
      this.setContentType();
      resultData = data;
    }
    xhr.send(resultData);
  }
  // Whether data needs to be carried in SEND
  isSendData() {
    // Data is the data carried by the request body
    const { data, method } = this.options;
    Xhr. send(null); // If data does not exist, return false;
    if(! data)return false;
    // If it is a GET request, it does not matter whether it is passed or not, return false
    if (method.toLowerCase() === "GET".toLowerCase()) return false;
    return true;
  }

  //// Determine whether it is formData and process it if it is
  isFormData() {
    return this.options.data instanceof FormData;
  }
  //// Determine whether the data is in name-value pair format
  isFormURLEncodedData() {
    return this.options.contentType
      .toLowerCase()
      .includes("application / x - www - form - urlencoded");
  }
//// Check whether the data is in JSON format
  isJsonData() {
    return this.options.contentType.toLowerCase().includes("application/json");
  }
  //// is converted to a string in JSON format
  serializeJson(param) {
    return JSON.stringify(param);
  }
  setContentType(contentType = this.options.contentType) {
    if(! contentType)return;
    this.xhr.setRequestHeader("Content-Type", contentType);
  }
  // Get the XHR object
  getXHR() {
    return this.xhr; }}export default Ajax;
Copy the code

Step 2: Create an index.js to instantiate several methods for external use

import Ajax from ./ajax.js;

const ajax=(url,options) = >{
   return new Ajax(url,options).getXHR()
}
// Define a get request to override the parameters passed by the user
const get=(url,options) = >{
    returnajax(url,{... options,method:'GET'})}// Define the get request to send JSON data overwriting the parameters passed by the user
const getJSON=(url,options) = >{
    returnajax(url,{... options,responseType:'json'})}/ / post request
const post=(url,options) = >{
    returnajax(url,{... options,method:'POST'})}export {
    ajax,get,getJSON,post
}
Copy the code

Step 3: Simulate sending the request

<script>
import {ajax,get,getJSON,post} from './index.js'
 const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
      const xhr = ajax(url, {
        method: 'GET'.params: { username: 'alex' },
        data: {
          age: 18
        },
        responseType: 'json'.// timeoutTime: 10,

        success(response) {
          console.log(response);
        },
        httpCodeError(err) {
          console.log('http code error', err);
        },
        error(xhr) {
          console.log('error', xhr);
        },
        abort(xhr) {
          console.log('abort', xhr);
        },
        timeout(xhr) {
          console.log('timeout', xhr); }}); xhr.abort();<script/>
Copy the code

3. Encapsulate Ajax with Promise

import Ajax from "./ajax.js";

const ajax = (url, options) = > {
  // return new Ajax(url, options).getXHR();
  let xhr;
  const p = new Promise((resolve, reject) = > {
    xhr = newAjax(url, { ... options, ... {success(response) {
          resolve(response);
        },
        httpCodeError(status) {
          reject({
            type: "ERROR_HTTP_CODE".text: `${status}`}); },error() {
          reject({
            type: "ERROR_REQUEST".text: "Request error"}); },abort() {
          reject({
            type: "ERROR_ABORT".text: "Unsend"}); },timeout() {
          reject({
            type: "ERROR_TIMEOUT".text: "Request timed out"}); }, }, }).getXHR(); }); p.xhr = xhr;return p;
};

const get = (url, options) = > {
  returnajax(url, { ... options,method: "GET" });
};

const getJSON = (url, options) = > {
  returnajax(url, { ... options,method: "GET".responseType: "json" });
};

const post = (url, options) = > {
  returnajax(url, { ... options,method: "POST" });
};

export { ajax, get, getJSON, post };
Copy the code

Send a request:

<script>
      import { ajax, get, getJSON, post } from "./ajax/index.js";

      const url = "https://www.imooc.com/api/http/search/suggest?words=js";
   

      const p = getJSON(url, {
        params: { username: "alex" },
        data: { age: 18 },
        // timeoutTime: 10,
      }).then((res) = > {
        console.log(res);
      });
      p.catch((err) = > {
        console.log(err);
      });
</script>
Copy the code

4. Ajax applications

Ajax Applications – Search tips

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>Search tips</title>
  </head>
  <body>
    <input id="search" type="text" />
    <ul id="result"></ul>
    <script type="module">
      import { getJSON } from "./ajax/index.js";
      const url = "https://www.imooc.com/api/http/search/suggest?words=";

      const searchInput = document.getElementById("search");
      const resultList = document.getElementById("result");
      function handInputEvent() {
        if(searchInput.value.trim() ! = ="") {
          getJSON(`${url}${searchInput.value}`).then((res) = > {
            console.log(res);

            let html = "";
            for (const item of res.data) {
              html += `<li>${item.word}<li>`;
            }
            resultList.innerHTML = html;
            resultList.style.display = "";

            res;
          });
        } else {
          resultList.innerHTML = "";
          resultList.style.display = "none"; }}let timer = null;
      searchInput.addEventListener("input".() = > {
        // handInputEvent(searchInput);

        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(handInputEvent, 2000);
      });
    </script>
  </body>
</html>

Copy the code

Ajax Applications – Secondary menu

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>The secondary menu</title>
    <style>
      /* css reset */
      * {
        padding: 0;
        margin: 0;
      }
      li {
        list-style: none;
      }

      /* menu */
      .menu {
        width: 100px;
        background-color: rgba(0.0.0.0.1);
        margin: 10px;
      }
      .menu-item {
        position: relative;
        padding: 5px;
        cursor: pointer;
      }
      .menu-content {
        display: none;
        position: absolute;
        left: 100%;
        top: 0;
        width: 200px;
        height: 100px;
        padding: 0 5px;
        background-color: rgba(0.0.0.0.1);
      }
      .menu-item:hover {
        background-color: rgba(0.0.0.0.4);
      }
      .menu-item:hover .menu-content {
        display: block;
      }
      .menu-loading {
        margin: 45px 0 0 92px;
      }
    </style>
  </head>
  <body>
    <ul id="menu" class="menu">
      <! -- <li class="menu-item" data-key="hot" data-done="done"> <span> <span> <div class="menu-content"> <p><img Class = "menu - loading" SRC = ". / loading. GIF "Alt =" loaded "/ > < / p > < / div > < / li > -- >
    </ul>

    <script type="module">
      // https://www.imooc.com/api/mall-PC/index/menu/hot
      // https://www.imooc.com/api/mall-PC/index/menu

      import { getJSON } from './ajax/index.js';
      const menuURL = 'https://www.imooc.com/api/mall-PC/index/menu';
      const menuEl = document.getElementById('menu');

      getJSON(menuURL)
        .then(repsonse= > {
          // console.log(repsonse);

          let html = ' ';

          for (const item of repsonse.data) {
            html += `
              <li class="menu-item" data-key="${item.key}">
                <span>${item.title}< / span > < div class = "menu - the content" > < p > < img class = "menu - loading" SRC = ". / loading. GIF "Alt =" loaded "/ > < / p > < / div > < / li > `;
          }

          menuEl.innerHTML = html;

          / / [{key: "hot", the title: "hot point of departure", subTitles: Array (5)}]

          // ...
        })
        .then(() = > {
          const items = menuEl.querySelectorAll('.menu-item');

          for (const item of items) {
            item.addEventListener(
              'mouseenter'.() = > {
                // console.log(item.getAttribute('data-key'));

                // IE11 starts support
                // console.log(item.dataset.key);
                // To prevent duplicate sending, do not send already sent
                if (item.dataset.done === 'done') return;

                getJSON(
                  `https://www.imooc.com/api/mall-PC/index/menu/${item.dataset.key}`
                )
                  .then(repsonse= > {
                    // console.log(repsonse);

                    // [{title: "hot cities ", Array(27)}]

                    item.dataset.done = 'done';

                    let html = ' ';

                    for (const item of repsonse.data) {
                      html += `<p>${item.title}</p>`;
                    }

                    item.querySelector('.menu-content').innerHTML = html;
                  })
                  .catch(err= > {
                    console.log(err);
                  });
              },
              false
            );
          }
        })
        .catch(err= > {
          console.log(err);
        });
    </script>
  </body>
</html>

Copy the code

Ajax applications – Concurrent execution of multiple Ajax requests

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Concurrent execution of multiple Ajax requests</title>
    <style>
      /* css reset */
      * {
        padding: 0;
        margin: 0;
      }
      li {
        list-style: none;
      }

      /* menu */
      .menu {
        width: 100px;
        background-color: rgba(0.0.0.0.1);
        margin: 10px;
      }
      .menu-item {
        position: relative;
        padding: 5px;
        cursor: pointer;
      }
      .menu-content {
        display: none;
        position: absolute;
        left: 100%;
        top: 0;
        width: 200px;
        height: 100px;
        padding: 0 5px;
        background-color: rgba(0.0.0.0.1);
      }
      .menu-item:hover {
        background-color: rgba(0.0.0.0.4);
      }
      .menu-item:hover .menu-content {
        display: block;
      }
      .menu-loading {
        margin: 45px 0 0 92px;
      }

      /* loading-page */
      .loading-page {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1000;
        background-color: #eee;
        text-align: center;
      }
      .loading-img {
        position: absolute;
        top: 50%;
      }
      .ad img {
        display: inline-block;
        width: 25%;
      }
      .none {
        display: none;
      }
    </style>
  </head>
  <body>
    <div id="loading-page" class="loading-page">
      <img class="loading-img" src="./loading.gif" alt="Loading" />
    </div>

    <div id="ad" class="ad"></div>

    <ul id="menu" class="menu">
      <! -- <li class="menu-item" data-key="hot" data-done="done"> <span> <span> <div class="menu-content"> <p><img Class = "menu - loading" SRC = ". / loading. GIF "Alt =" loaded "/ > < / p > < / div > < / li > -- >
    </ul>
    <script type="module">
      import { getJSON } from './ajax/index.js';

      const menuURL = 'https://www.imooc.com/api/mall-PC/index/menu';
      const adURL = 'https://www.imooc.com/api/mall-PC/index/ad';

      const loadingPageEl = document.getElementById('loading-page');
      const adEl = document.getElementById('ad');
      const menuEl = document.getElementById('menu');

      const p1 = getJSON(menuURL)
        .then(repsonse= > {
          // console.log(repsonse);

          let html = ' ';

          for (const item of repsonse.data) {
            html += `
              <li class="menu-item" data-key="${item.key}">
                <span>${item.title}< / span > < div class = "menu - the content" > < p > < img class = "menu - loading" SRC = ". / loading. GIF "Alt =" loaded "/ > < / p > < / div > < / li > `;
          }

          menuEl.innerHTML = html;

          / / [{key: "hot", the title: "hot point of departure", subTitles: Array (5)}]

          // ...
        })
        .then(() = > {
          const items = menuEl.querySelectorAll('.menu-item');

          for (const item of items) {
            item.addEventListener(
              'mouseenter'.() = > {
                // console.log(item.getAttribute('data-key'));

                // IE11 starts support
                // console.log(item.dataset.key);

                if (item.dataset.done === 'done') return;

                getJSON(
                  `https://www.imooc.com/api/mall-PC/index/menu/${item.dataset.key}`
                )
                  .then(repsonse= > {
                    // console.log(repsonse);

                    // [{title: "hot cities ", Array(27)}]

                    item.dataset.done = 'done';

                    let html = ' ';

                    for (const item of repsonse.data) {
                      html += `<p>${item.title}</p>`;
                    }

                    item.querySelector('.menu-content').innerHTML = html;
                  })
                  .catch(err= > {
                    console.log(err);
                  });
              },
              false
            );
          }
        })
        .catch(err= > {
          console.log(err);
        });

      const p2 = getJSON(adURL)
        .then(response= > {
          // console.log(response);
          // [{ url: 'http://alimc.img.imooc.com/class/' }];

          let html = ' ';
          for (const item of response.data) {
            html += `<img src="${item.url}" alt="" />`;
          }
          adEl.innerHTML = html;
        })
        .catch(err= > {
          console.log(err);
        });

      Promise.all([p1, p2]).then(() = > {
        // loadingPageEl.style.display = 'none';

        // IE10 starts support
        loadingPageEl.classList.add('none');
        // loadingPageEl.classList.remove('none');
      });
    </script>
  </body>
</html>
Copy the code

Part seven axios

Axios official website: Portal

1. What is Axios?

Axios is a Promise-based HTTP library that can be used in browsers and Node.js. The feature creates XMLHttpRequests from the browser to create HTTP request support from Node.jsPromiseAPI intercepts request and response conversion request data and response data cancellation request automatic conversionJSONData clients support XSRF defenseCopy the code

2. Procedure for using AXIos

Step 1: Introduction// npm install axios

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
const url = "https://www.imooc.com/api/http/search/suggest?words=js";
//1. Use axios()
    axios(url, {
      // Request mode
      method: "post".// Request header information
      headers: {
        "Content-Type": "application/x-www-form-urlencoded".// "Content-Type": "application/json",
      },
      // Data carried through the request header
      params: {
        username: "alex",},// The data carried by the request body
      // If such an object is passed, it will be passed in JSON format, and the content-type needs to be set to the specified JSON format
      // data: {
      // age: 19,
      // sex: "male",
      // },
      data: "age=18&sex=male",
    })
      .then((response) = > {
        console.log(response);
        console.log(response.data.data);
      })
      .catch((err) = > {
        console.log(err);
      });
//2. Use the axios.get() method:
    axios
      .get(url, {
        params: { username: "alex" },
      })
      .then((response) = > {
        console.log(response);
      });
    // Content-Type does not need to be set, but is automatically set according to the format of the parameters you pass
 / / 3. Axios. Post () method:
    axios.post(url, { username: "alex" }).then((response) = > {
      console.log(response);
    });
Copy the code

3. Some properties of axios()

 <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
      axios({
        url: "https://www.imooc.com/api/http/search/suggest?words=js".baseURL: "".method: "post".// default
        // 'headers' is a custom request header to be sent
        // Show the server my format, the server will do different processing for this format
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        // headers: { "Content-Type": "application/json" },
        // 'params' is the URL parameter to be sent with the request. It must be a plain Object or URLSearchParams object
        // This will automatically compile to '? '"&" passes the format of the parameter to the request address
        params: {
          ID: 12345.name: "CAI Xukun",},/* data: POST is the data that is sent as the body of the request (it is sent in json format by default and needs to be processed into a string to match the header) */
        data: {
          firstName: "Fred111",},transformRequest:function(data){
            return Qs.stringify(data)
        },
        // timeout Specifies the number of milliseconds in which the request will timeout (0 indicates no timeout) and the request will be interrupted
        timeout: 0.// withCredentials indicates whether credentials are needed for cross-domain requests
        withCredentials: false.// default

        // responseType converts the data type returned from the server to our default format, which can be 'arrayBuffer ', 'blob', 'document', 'json', 'text', 'stream'
        responseType: "json".// default
      }).then((response) = > {
        console.log(response);
      });
    </script>
Copy the code

4. The public property of axios() is stripped

  <! -- Step 1: Introduce -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
      // Step 2: Configure the default information
      axios.defaults.baseURL = "https://www.imooc.com";
      axios.defaults.headers["Content-Type"] =
        "application/x-www-form-urlencoded";

      // Add request interceptor
      axios.interceptors.request.use(
        function (config) {
          // What to do before sending the request
          return config;
        },
        function (error) {
          // What to do about the request error
          return Promise.reject(error); });Interceptor: Intercepts requests or responses before they are processed by then or catch. Set a response interceptor: [success state] gets the response body information from the result obtained from the server. [failure state] Manually throws an exception
      axios.interceptors.response.use(
        function (response) {
          // Get data from the server
          return response.data;
        },
        function (error) {
          // No data was retrieved from the server
          return Promise.reject(error); });// Step 3: Send your own separate request
      axios
        .get("/api/http/search/suggest? words=js", {
          params: {
            name: "xxxx".age: 19,
          },
        })
        .then((response) = > {
          console.log(response);
        });

      axios
        .post(
          "/api/http/search/suggest? words=js",
          {
            name: "cccccc".age: 123213,
          },
          {}
        )
        .then((s) = > {
          console.log(s);
        });
    </script>
Copy the code

Part 8 Fetch

Fetch latest portal

  • Fetch is also a means of communication between the front and back ends
  • Fetch is an alternative to the XMLHttpRequest object, which is based on Promise and is provided natively by browsers

1. Fetch () differs from XMLHttpRequest:

    1. Calling fetch(URL) directly returns the Promise object.
    1. Fetch () has a modular design, with apis scattered over multiple objects (Response, Request, Headers), which makes more sense. In contrast, XMLHttpRequest’s API design is not very good, and the input, output, and state are all managed on the same interface, making it easy to write very messy code
    1. Fetch () processes data through a Stream object and can be read in chunks, which is helpful for improving website performance and reducing memory footprint. It is useful for scenarios requiring large files or slow network speeds. The XMLHTTPRequest object does not support data streaming. All data must be stored in the cache. It cannot be read in chunks.

2. The basic usage of fetch

  • 1. Fetch () can accept only a URL string as an argument, and by default makes a GET request to that URL, returning a Promise object
      const url = "https://www.imooc.com/api/http/search/suggest?words=";

      fetch(url)
        .then(function (response) {
          // console.log(response); It can only read once
          // Whether the request was successful
          if (response.ok) {
            return response.json();
          } else {
            throw new Error(The status code is abnormal${response.status}`);
          }
        })
        .then(function (responseData) {
          console.log(responseData.data);
        })
        .catch((err) = > {
          console.log(err);
        });
Copy the code

Rewrite with await:

async function getJSON() {
  let url = 'https://api.github.com/users/ruanyf';
  try {
    let response = await fetch(url);
    return await response.json();
  } catch (error) {
    console.log('Request Failed', error); }}Copy the code

3. the second argument to fetch() : customizing the HTTP request

3.1 Sending A POST Request and JSON Data

const user =  { name:  'John'.surname:  'Smith'  };
const response = await fetch('/article/fetch/post/user', {
  method: 'POST'.headers: {
   'Content-Type': 'application/json; charset=utf-8'
  }, 
  body: JSON.stringify(user) 
});
Copy the code

3.2 Sending POST requests and key-value data

const response = await fetch(url, {
  method: 'POST'.headers: {
    "Content-type": "application/x-www-form-urlencoded; charset=UTF-8",},body: 'foo=bar&lorem=ipsum'});Copy the code

3.3 Post submission of the form

const form = document.querySelector('form');

const response = await fetch('/users', {
  method: 'POST'.body: new FormData(form)
})
Copy the code

3.4 Uploading a File through Post

const input = document.querySelector('input[type="file"]');

const data = new FormData();
data.append('file', input.files[0]);
data.append('user'.'foo');

fetch('/avatars', {
  method: 'POST'.body: data
});
Copy the code

4.Response object: Processes HTTP responses

  • After the fetch() sends the request, fetch() will only report an error if the network is faulty, or if the connection is not available. In other cases, fetch() will not report an error, but will consider the request successful.
  • Only when fetch() sends a request and obtains the real status code of the HTTP Response through the response. status attribute, can the request be judged to be successful.
  • The first judgment method: Response. status attribute must be equal to 2xx (200~299), the request can be regarded as successful. Don’t worry about url jumps (status code 3xx) because fetch() automatically changes the jump’s status code to 200.
  • Another method is to determine if response.ok is true. The response. ok property returns a Boolean value,Indicates whether the request was successful, true corresponds to the HTTP request status codes 200 to 299, false corresponds to other status codes.
async function fetchText() {
  let response = await fetch('/readme.txt');
  if (response.status >= 200 && response.status < 300) {
    return await response.text();
  } else {
    throw new Error(response.statusText); }}/ / or
if (response.ok) {
  // The request succeeded
} else {
  // The request failed
}
Copy the code
  • Response.headers. Get (), which reads the value of a header.
let response =  await  fetch(url);  
response.headers.get('Content-Type')
// application/json; charset=utf-8
Copy the code
  • Read text contents:
  • Response.text () : Gets the text string.
  • Response.json () : Gets the JSON object.