(turn) This API is "fascinating"--the new fetch API

Source: Internet
Author: User

Original: Https://hacks.mozilla.org/2015/03/this-api-is-so-fetching

The original title is the This API are so fetching,fetching also can be expressed as charming meaning--translator note

JavaScript executes asynchronous requests through XMLHttpRequest (XHR), which has existed for a long time. Although it is useful, it is not the best API. It is not designed to conform to the separation of duties principle, the input, output and events to track the status of the mixed in an object. Moreover, the event-based model is not very well-timed with the recent JavaScript popular promise and the generator-based Asynchronous programming model (the event model is a bit outdated in processing async-the translator notes).

The new Fetch API intends to fix the bugs mentioned above. It introduces to JS the same primitive as the HTTP protocol (i.e. the fetch--translator Note). Specifically, it introduces a useful function to simply fetch() capture the intent of retrieving a resource from the network.

The FETCH specification API explicitly describes the semantics of user-agent access to resources. It combines serviceworkers to try to achieve the following optimizations:

    1. Improve your offline experience
    2. Maintain scalability

By the time this article was written, the Fetch API was supported by Firefox (version nightly) and Chrome 42 (development). On GitHub, a compatible implementation based on a low-version browser

Feature detection

To check whether the fetch API is supported, you can check for Headers, Request, Response, or fetch in the window or worker scope.

A simple fetching example

In the Fetch API, the most common is the fetch () function. It receives a URL parameter and returns a promise to handle the response. The response parameter carries a response object.

Fetch ("/data.json"). Then (function(res) {  //  res instanceof Response = = True.  if (Res.ok) {    Res.json (). Then (function(data) {      console.log (data.entries);    });   Else  {    console.log ("Looks like the response wasn ' t perfect, got status", Res.status);   function (e) {  console.log ("Fetch failed!") , E);});

If you are submitting a POST request, the code is as follows:

Fetch ("http://www.example.org/submit.php", {method:"POST", headers: {"Content-type": "application/x-www-form-urlencoded"}, Body:"Firstname=nikhil&favcolor=blue&password=easytoguess"}). Then (function(res) {if(Res.ok) {alert ("Perfect! Your settings is saved. "); } Else if(Res.status = = 401) {alert ("Oops! You is not authorized. "); }}, function(e) {alert ("Error Submitting form!");});

The parameters of the fetch () function remain exactly the same as the parameters passed to the request () constructor, so you can pass any complex request to fetch () directly.

Headers

Fetch introduces 3 interfaces, which are headers,request and Response, respectively. They correspond directly to the corresponding HTTP concept, but for security reasons, there are some differences, such as the support for Cors rules and the assurance that cookies cannot be obtained by third parties.

The headers interface is a simple multi-mapped name-value table

var content = "Hello world"; var New Headers (); Reqheaders.append ("Content-type", "Text/plain"reqheaders.append ("Content-length" , content.length.toString ()); Reqheaders.append ("X-custom-header", "processthisimmediately");

You can also pass a multidimensional array or JSON:

New Headers ({  "Content-type": "Text/plain",  "Content-length": Content.length.toString (),  "X-custom-header": "Processthisimmediately",});

The contents of the headers can be retrieved:

Console.log (Reqheaders.has ("Content-type"));//trueConsole.log (Reqheaders.has ("Set-cookie"));//falseReqheaders.set ("Content-type", "text/html"); Reqheaders.append ("X-custom-header", "Anothervalue"); Console.log (Reqheaders.get ("Content-length"));// OneConsole.log (Reqheaders.getall ("X-custom-header"));//["processthisimmediately", "Anothervalue"]reqheaders.Delete("X-custom-header"); Console.log (Reqheaders.getall ("X-custom-header"));// []

Some operations are not only useful for serviceworkers, but also provide a more convenient API for manipulating headers (as opposed to XMLHttpRequest).

The headers object has a special guard attribute because the headers can be sent in the requests request or received in the response request and specifies which parameters are writable. This property is not exposed to the web, but it affects which content can be changed in the headers object.

The possible values are as follows:

    • "None": the Default
    • "Request": the headers obtained from the request is read-only.
    • "Request-no-cors": headers read-only obtained from request from different domains.
    • "Response": The headers obtained from response is read-only.
    • "Immutable" is most commonly used in serviceworkers, and all headers are read-only.

What kind of guard acts on Headers cause what behavior is defined in detail in this specification. For example, you may not add or modify a guard property that is the "content-length" property of request Headers "request". Similarly, inserting the "Set-cookie" attribute into a response headers is not allowed, so serviceworkers is not able to add some cookies to the response of the composition headers.

If an illegal HTTP header property name is used, the headers method usually throws a TypeError exception. If you accidentally write a non-writable property, a TypeError exception is thrown. In addition, failure does not throw an exception. For example:

var res = response.error (); Try {  res.headers.set ("Origin", "http://mybank.com"catch(e) {  Console.log ( "cannot pretend to be a bank!" );}

Request

The request interface defines the requested format for requesting resources over HTTP. Parameters require URLs, method, and headers, and the request accepts a specific body,mode,credentials as well as the cache hints.

The simplest Request is of course a URL that can be used to get a resource through a URL.

var New Request ("/index.html"//  "GET"//  "http://example.com/index.html "

You can also pass a built request object to the constructor, which will copy a new request.

var New  //  "GET"//  "http://example.com/index.html"

This usage is usually seen in serviceworkers.

The initial value of a property other than a URL can be passed to the request constructor through the second argument. This parameter is a JSON:

var New Request ("/uploadimage", {  "POST",  headers: {    "Content-type": "Image/png",  } ,  "image Data"});

modeThe response property is used to determine whether cross-domain requests are allowed and which properties are readable. The optional Mode property value is same-origin , no-cors (default), and cors .

same-originThe pattern is simple, if a request is cross-domain, return a simple error so that all requests follow the same-origin policy.

var arbitraryurl = document.getElementById ("url-input""Same-origin"}). Then (function (res) {  console.log ("Response succeeded?")  function(e) {  console.log ("Please enter a same-origin url!" );});

no-corsSchemas allow scripts from the CDN, images from other domains, and other cross-domain resources, but first there is a precondition that the requested method can only be "HEAD", "GET" or "POST". In addition, any serviceworkers intercepts these requests, and it cannot arbitrarily add or overwrite any headers, except for these. Third, JavaScript does not have access to any of the properties in response, which ensures that serviceworkers does not cause any cross-domain security issues and privacy information leaks.

corsPatterns we typically use cross-domain requests to get data from a third-party API. This mode adheres to the Cors protocol. Only a limited number of headers are exposed to response objects, but the body is readable. For example, you can get a list of the most interesting photos of Flickr:

varU =Newurlsearchparams (); U.append (' Method ', ' flickr.interestingness.getList '); U.append (' Api_key ', ' <insert API Key Here> '); U.append (' Format ', ' JSON '); U.append (' Nojsoncallback ', ' 1 ');varApicall = Fetch (' https://api.flickr.com/services/rest? ' +u); Apicall.then (function(response) {returnResponse.json (). Then (function(JSON) {//photo is a list of photos.    returnJson.photos.photo; });}). Then (function(Photos) {Photos.foreach (function(photo) {Console.log (photo.title); });});

You cannot read the "Date" property from headers because Flickr has set up in access-control-expose-headers not to allow it to be read.

// NULL

credentialsThe enumeration attribute determines whether cookies can be obtained across domains. This property is the same as the Withcredentials flag for XHR, but there are only three values, namely "omit" (default), "Same-origin", and "include".

The request object can also provide caching hints to the user agent. This attribute is also in the security Review phase. Firefox provides this property, but it doesn't work at this time.

Request also has two read-only properties related to Serviceworks interception. One of them is referrer, which indicates the source of the request and may be empty. The other is the context, which is a very large enumeration set that defines the kind of resources obtained, which may be image such as requests coming from an IMG tag, possibly worker a worker script, and so on. If you use the Fetch () function, this value is fetch .

Response

Response instances are usually obtained in callbacks of Fetch (). But they can also be constructed with JS, but this is usually used only for serviceworkers.

The most common members of response are status (an integer default is 200) and statustext (the default is "OK"), corresponding to the status and reason of the HTTP request. There is also an "OK" attribute, which is true when status is 2xx.

The Headers property is a headers object of response, which is read-only (with guard "response"), and the URL property is the source URL of the current response.

Response also has a type attribute whose value may be "basic", "Cors", "Default", "Error" or "opaque".

    • "Basic": normal, same-domain request, including all headers except "Set-cookie" and "Set-cookie2".
    • "Cors": response is obtained from a legitimate cross-domain request, with a portion of the header and body readable.
    • "Error": Network error. The status of response is 0,headers is empty and is not writable. This is the type when response is obtained from the Response.error ().
    • "Opaque": Response requests cross-domain resources from "no-cors". Rely on server side to make restrictions.

The "error" type causes the promise of the fetch () function to be reject and a typeerror is recalled.

There are also some properties that are only valid under the Serverworker scope. Return a response in the right way for a request that is intercepted by Serviceworkers, you can write as follows:

function (event) {  event.respondwith (new Response ("Response body", {    "Content-type": " Text/plain " }  );});

As you can see, response has a constructor that receives two optional arguments. The first parameter is the body returned, the second parameter is a JSON, set status, StatusText, and headers.

The static method Response.error () simply returns an incorrect request. Similarly, Response.Redirect (URL, status) returns a request for a jump URL.

Handling body

Both the request and the response may carry the body. Because the body can be various types, more complex, so we deliberately skip it before, here alone to explain.

Body can be an instance of any of the following types:

    • ArrayBuffer
    • Arraybufferview (Uint8array and friends)
    • Blob/file
    • String
    • Urlsearchparams
    • formdata--is not currently supported by Gecko and Blink, and Firefox is expected to be rolled out in version 39 and other parts of the fetch.

In addition, both request and response provide the following methods for their body, which all return a Promise object.

    • ArrayBuffer ()
    • Blob ()
    • JSON ()
    • Text ()
    • FormData ()

The Fetch API and XHR provide great convenience when using non-textual data.

The body of the request can be set by passing the body parameter:

var New FormData (document.getElementById (' Login-form ')); Fetch ("/login", {  "POST",  body: form})

The first parameter of the response is the body:

var New Response (new File (["Chunk", "chunk"], "Archive.zip",                       "Application/zip"});

Both request and response (via the Fetch () method) automatically identify their Content type,request and can automatically set the "Content-type" header if the developer doesn't set it up.

Stream and Clone

It is important to note that the body of request and response can only be read once! They have a property called bodyused, which, after reading once, is set to true and can no longer be read.

var New Response ("One time use"//  falseRes.text (). Then (function(v) {     true//  trueres.text (). Catch (function(e) {  console.log ("tried to read already consumed Response") ;

The purpose of this design is to later be compatible with stream-based APIs, allowing the application to consume data once, allowing JavaScript to process large files such as video, and support real-time compression and editing.

Sometimes, we want to access the body multiple times, for example, you might want to cache the request and response with the cache API that is about to be supported, so that it can be used offline, and the cache requires the body to be read again.

So how do we make the body stand up to multiple reads? The API provides a clone () method. Call this method to get a cloned object. Remember, however, that clone () must be called before reading, that is, Clone () before reading.

AddEventListener (' Fetch ',function(evt) {varSheep =NewResponse ("Dolly"); Console.log (sheep.bodyused); //false  varClone =Sheep.clone (); Console.log (clone.bodyused); //falseClone.text (); Console.log (sheep.bodyused); //falseConsole.log (clone.bodyused);//trueEvt.respondwith (Cache.Add (Sheep.clone ()). Then (function(e) {returnsheep; });});

Improvements in the future

In order to support streaming, Fetch will eventually provide the ability to interrupt the execution of read resources and provide APIs that can get read progress. These capabilities are available in XHR, but it's a bit cumbersome to implement the fetch API into promise-based.

(GO) This API is "fascinating"-New fetch API

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.