Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the ways in which the front end makes network requests?

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly shows you "what are the ways to make network requests at the front end". The content is easy to understand and clear. I hope it can help you solve your doubts. Let me lead you to study and learn the article "what are the ways to make network requests at the front end?"

First, the focus of the front-end network request

In most cases, to initiate a network request at the front end, we only need to focus on the following points:

Pass in basic parameters (url, request method)

Request parameters, request parameter types

Set request header

How to get the response

Get response header, response status, response result

Exception handling

Carry cookie settings

Cross-domain request

Second, the way the front end makes the network request

Form forms, ifream, refresh pages

Ajax-the originator of asynchronous network requests

JQuery-an era

The replacement of fetch-Ajax

Axios, request and many other open source libraries

Third, questions about network requests

What problems have been solved by the emergence of Ajax

How to use native Ajax

The network request mode of jQuery

The usage and pitfalls of fetch

How to use fetch correctly

How to choose the appropriate cross-domain approach

With the above questions and concerns, we make a comprehensive analysis of several network requests.

4. What problems have been solved by the emergence of Ajax

Before Ajax, the web program worked like this:

The drawback of this interaction is obvious, any interaction with the server needs to refresh the page, the user experience is very poor, the emergence of Ajax solves this problem. Ajax full name Asynchronous JavaScript + XML (Asynchronous JavaScript and XML)

With Ajax, web applications can quickly render incremental updates to the user interface without reloading (refreshing) the entire page.

Ajax itself is not a new technology, but is used to describe a technical solution implemented using a collection of existing technologies, and the browser's XMLHttpRequest is the most important object for implementing Ajax (ActiveXObject is used below IE6).

Although X stands for XML in Ajax, JSON is currently more commonly used than XML because of many of the advantages of JSON, such as being lighter and as part of Javascript.

Fifth, the usage of native Ajax

Here is the main analysis of the XMLHttpRequest object, here is a section of its basic use:

Var xhr = new XMLHttpRequest ()

Xhr.open ('post','www.xxx.com',true)

/ / receive the return value

Xhr.function () {

If (xhr.readyState = 4) {

If (xhr.status > = 200 & & xhr.status

< 300) || xhr.status == 304){ console.log(xhr.responseText); } } } // 处理请求参数 postData = {"name1":"value1","name2":"value2"}; postData = (function(value){ var dataString = ""; for(var key in value){ dataString += key+"="+value[key]+"&"; }; return dataString; }(postData)); // 设置请求头 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 异常处理 xhr.{ console.log('Network request failed') } // 跨域携带cookie xhr.withCredentials = true; // 发出请求 xhr.send(postData); 复制代码 下面分别对XMLHttpRequest对象常用的的函数、属性、事件进行分析。

Function

Open

Used to initialize a request, usage:

Xhr.open (method, url, async)

Copy the code

Method: request method, such as get, post

Url: the requested url

Async: whether it is an asynchronous request

Send

Used to send a HTTP request, that is, the HTTP request will not be actually issued until the method is called. Usage:

Xhr.send (param)

Copy the code

The parameters of param:http request can be string, Blob, and so on.

Abort

Used to terminate an ajax request. After calling this method, readyState will be set to 0. Usage:

Xhr.abort ()

Copy the code

SetRequestHeader

Used to set the HTTP request header, this method must be called between the open () method and send (), usage:

Xhr.setRequestHeader (header, value)

Copy the code

GetResponseHeader

Used to get a http return. If there is more than one same name in the return, the returned value will be a string separated by commas and spaces. Usage:

Var header = xhr.getResponseHeader (name)

Copy code properties

ReadyState

Used to identify the state of the current XMLHttpRequest object, the XMLHttpRequest object is always in one of the following states:

Status

Represents the status of the http request, with an initial value of 0. If the server does not explicitly specify the status code, then status will be set to the default value of 200.

ResponseType

Indicates the data type of the response, and allows us to set it manually. If it is empty, the default is text. You can have the following values:

Response

Returns the body of the response, and the type returned is determined by the responseType above.

WithCredentials

Ajax requests carry the cookie of the same origin request by default, while cross-domain requests do not carry cookie. Setting the withCredentials attribute of xhr to true will allow you to carry cross-domain cookie.

Event callback

Onreadystatechange

Xhr.callback

Copy the code

Callback is triggered when the readyState property changes.

Onloadstart

Xhr.callback

Copy the code

Before the ajax request is sent (after readyState==1, before readyState==2), callback will be triggered.

Onprogress

Xhr.function (event) {

Console.log (event.loaded / event.total)

}

Copy the code

The callback function can get the total resource size total and the loaded resource size loaded, which can be used to calculate the loading progress.

Onload

Xhr.callback

Copy the code

Callback is triggered when a resource and its dependent resources have finished loading, and we usually handle the return value in the onload event.

Exception handling

Onerror

Xhr.callback

Copy the code

Callback is triggered when the ajax resource fails to load.

Ontimeout

Xhr.callback

Copy the code

When the schedule is terminated due to the expiration of the scheduled time, callback is triggered, and the timeout can be set using the timeout property.

VI. Encapsulation of Ajax by jQuery

For a long time, people used the ajax encapsulation provided by jQuery to make web requests, including $.ajax, $.get, $.post, etc., which I still find very useful.

$.ajax ({

DataType: 'json', / / sets the return value type

ContentType: 'application/json', / / set parameter type

Headers: {'Content-Type','application/json'}, / / set the request header

XhrFields: {withCredentials: true}, / / Cross-domain carrying cookie

Data: JSON.stringify ({a: [{bvl, aRV 1}]}), / / pass parameters

Error:function (xhr,status) {/ / error handling

Console.log (xhr,status)

}

Success: function (data,status) {/ / get the result

Console.log (data,status)

}

})

Copy the code

Ajax receives only one parameter, which receives a series of configurations and encapsulates a jqXHR object. If you are interested, you can read the jQuary-ajax source code.

Common configurations:

Url

The current page address. The address from which the request was sent.

Type

Type: String request method ("POST" or "GET"), default is "GET". Note: other HTTP request methods, such as PUT and DELETE, can also be used, but only some browsers support them.

Timeout

Type: Number sets the request timeout (milliseconds). This setting overrides the global setting.

Success

Type: callback function after a successful Function request.

Jsonp

Rewrite the name of the callback function in an jsonp request. This value is used instead of in "callback=?" The "callback" part of the URL parameter of this GET or POST request.

Error type: Function. This function is called when the request fails.

Note: the determination of errors in the source code:

IsSuccess = status > = 200 & & status

< 300 || status === 304; 复制代码 返回值除了这几个状态码都会进error回调。 dataType "xml": 返回 XML 文档,可用 jQuery 处理。 "html": 返回纯文本 HTML 信息;包含的 script 标签会在插入 dom 时执行。 "script": 返回纯文本 JavaScript 代码。不会自动缓存结果。除非设置了 "cache" 参数。注意:在远程请求时(不在同一个域下),所有 POST 请求都将转为 GET 请求。(因为将使用 DOM 的 script标签来加载) "json": 返回 JSON 数据 。 "jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。 "text": 返回纯文本字符串 复制代码 data 类型:String 使用JSON.stringify转码 complete 类型:Function请求完成后回调函数 (请求成功或失败之后均调用)。 async 类型:Boolean 默认值:true。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。 contentType 类型:String默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。 键值对这样组织在一般的情况下是没有什么问题的,这里说的一般是,不带嵌套类型JSON,也就是 简单的JSON,形如这样: { a: 1, b: 2, c: 3 } 复制代码 但是在一些复杂的情况下就有问题了。 例如在 Ajax中你要传一个复杂的 json 对像,也就说是对象嵌数组,数组中包括对象,你这样传:application/x-www-form-urlencoded 这种形式是没有办法将复杂的JSON组织成键值对形式。 { data: { a: [{ x: 2 }] } } 复制代码 可以用如下方式传递复杂的json对象 $.ajax({ dataType: 'json', contentType: 'application/json', data: JSON.stringify({a: [{b:1, a:1}]}) }) 复制代码七、jQuery的替代者 近年来前端MV*的发展壮大,人们越来越少的使用jQuery,我们不可能单独为了使用jQuery的Ajax api来单独引入他,无可避免的,我们需要寻找新的技术方案。 尤雨溪在他的文档中推荐大家用axios进行网络请求。axios基于Promise对原生的XHR进行了非常全面的封装,使用方式也非常的优雅。另外,axios同样提供了在node环境下的支持,可谓是网络请求的首选方案。 未来必定还会出现更优秀的封装,他们有非常周全的考虑以及详细的文档,这里我们不多做考究,我们把关注的重点放在更底层的APIfetch。 Fetch API是一个用用于访问和操纵HTTP管道的强大的原生 API。 这种功能以前是使用 XMLHttpRequest实现的。Fetch提供了一个更好的替代方法,可以很容易地被其他技术使用,例如 Service Workers。Fetch还提供了单个逻辑位置来定义其他HTTP相关概念,例如CORS和HTTP的扩展。 可见fetch是作为XMLHttpRequest的替代品出现的。 使用fetch,你不需要再额外加载一个外部资源。但它还没有被浏览器完全支持,所以你仍然需要一个polyfill。 八、fetch的使用 一个基本的 fetch请求: const options = { method: "POST", // 请求参数 headers: { "Content-Type": "application/json"}, // 设置请求头 body: JSON.stringify({name:'123'}), // 请求参数 credentials: "same-origin", // cookie设置 mode: "cors", // 跨域 } fetch('http://www.xxx.com',options) .then(function(response) { return response.json(); }) .then(function(myJson) { console.log(myJson); // 响应数据 }) .catch(function(err){ console.log(err); // 异常处理 }) 复制代码 Fetch API提供了一个全局的fetch()方法,以及几个辅助对象来发起一个网络请求。 fetch() fetch()方法用于发起获取资源的请求。它返回一个promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。 Headers 可以通过Headers()构造函数来创建一个你自己的headers对象,相当于 response/request 的头信息,可以使你查询到这些头信息,或者针对不同的结果做不同的操作。 var myHeaders = new Headers(); myHeaders.append("Content-Type", "text/plain"); 复制代码 Request 通过Request()构造函数可以创建一个Request对象,这个对象可以作为fetch函数的第二个参数。 Response 在fetch()处理完promises之后返回一个Response实例,也可以手动创建一个Response实例。 九、fetch polyfill源码分析 由于fetch是一个非常底层的API,所以我们无法进一步的探究它的底层,但是我们可以借助它的polyfill探究它的基本原理,并找出其中的坑点。 代码结构 由代码可见,polyfill主要对Fetch API提供的四大对象进行了封装: fetch 封装 代码非常清晰: 构造一个Promise对象并返回 创建一个Request对象 创建一个XMLHttpRequest对象 取出Request对象中的请求url,请求方发,open一个xhr请求,并将Request对象中存储的headers取出赋给xhr xhr onload后取出response的status、headers、body封装Response对象,调用resolve。 异常处理 可以发现,调用reject有三种可能: 1.请求超时 2.请求失败 注意:当和服务器建立简介,并收到服务器的异常状态码如404、500等并不能触发onerror。当网络故障时或请求被阻止时,才会标记为 reject,如跨域、url不存在,网络异常等会触发onerror。 所以使用fetch当接收到异常状态码都是会进入then而不是catch。这些错误请求往往要手动处理。 3.手动终止 可以在request参数中传入signal对象,并对signal对象添加abort事件监听,当xhr.readyState变为4(响应内容解析完成)后将signal对象的abort事件监听移除掉。 这表示,在一个fetch请求结束之前可以调用signal.abort将其终止。在浏览器中可以使用AbortController()构造函数创建一个控制器,然后使用AbortController.signal属性 这是一个实验中的功能,此功能某些浏览器尚在开发中 Headers封装 在header对象中维护了一个map对象,构造函数中可以传入Header对象、数组、普通对象类型的header,并将所有的值维护到map中。 之前在fetch函数中看到调用了header的forEach方法,下面是它的实现: 可见header的遍历即其内部map的遍历。 另外Header还提供了append、delete、get、set等方法,都是对其内部的map对象进行操作。 Request对象 Request对象接收的两个参数即fetch函数接收的两个参数,第一个参数可以直接传递url,也可以传递一个构造好的request对象。第二个参数即控制不同配置的option对象。 可以传入credentials、headers、method、mode、signal、referrer等属性。 这里注意: 传入的headers被当作Headers构造函数的参数来构造header对象。 cookie处理 fetch函数中还有如下的代码: if (request.credentials === 'include') { xhr.withCredentials = true } else if (request.credentials === 'omit') { xhr.withCredentials = false } 复制代码 默认的credentials类型为same-origin,即可携带同源请求的coodkie。 然后我发现这里polyfill的实现和MDN-使用Fetch以及很多资料是不一致的: mdn: 默认情况下,fetch 不会从服务端发送或接收任何 cookies 于是我分别实验了下使用polyfill和使用原生fetch携带cookie的情况,发现在不设置credentials的情况下居然都是默认携带同源cookie的,这和文档的说明说不一致的,查阅了许多资料后都是说fetch默认不会携带cookie,下面是使用原生fetch在浏览器进行请求的情况: 然后我发现在MDN-Fetch-Request已经指出新版浏览器credentials默认值已更改为same-origin,旧版依然是omit。 确实MDN-使用Fetch这里的文档更新的有些不及时,误人子弟了... Response对象 Response对象是fetch调用成功后的返回值: 回顾下fetch中对Response`的操作: xhr.() { var options = { status: xhr.status, statusText: xhr.statusText, headers: parseHeaders(xhr.getAllResponseHeaders() || '') } options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL') var body = 'response' in xhr ? xhr.response : xhr.responseText resolve(new Response(body, options)) } 复制代码 Response构造函数: 可见在构造函数中主要对options中的status、statusText、headers、url等分别做了处理并挂载到Response对象上。 构造函数里面并没有对responseText的明确处理,最后交给了_initBody函数处理,而Response并没有主动声明_initBody属性,代码最后使用Response调用了Body函数,实际上_initBody函数是通过Body函数挂载到Response身上的,先来看看_initBody函数: 可见,_initBody函数根据xhr.response的类型(Blob、FormData、String...),为不同的参数进行赋值,这些参数在Body方法中得到不同的应用,下面具体看看Body函数还做了哪些其他的操作: Body函数中还为Response对象挂载了四个函数,text、json、blob、formData,这些函数中的操作就是将_initBody中得到的不同类型的返回值返回。 这也说明了,在fetch执行完毕后,不能直接在response中获取到返回值而必须调用text()、json()等函数才能获取到返回值。 这里还有一点需要说明:几个函数中都有类似下面的逻辑: var rejected = consumed(this) if (rejected) { return rejected } 复制代码 consumed函数: function consumed(body) { if (body.bodyUsed) { return Promise.reject(new TypeError('Already read')) } body.bodyUsed = true } 复制代码 每次调用text()、json()等函数后会将bodyUsed变量变为true,用来标识返回值已经读取过了,下一次再读取直接抛出TypeError('Already read')。这也遵循了原生fetch的原则: 因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次 十、fetch的坑点 VUE的文档中对fetch有下面的描述: 使用fetch还有很多别的注意事项,这也是为什么大家现阶段还是更喜欢axios 多一些。当然这个事情在未来可能会发生改变。 由于fetch是一个非常底层的API,它并没有被进行很多封装,还有许多问题需要处理: 不能直接传递JavaScript对象作为参数 需要自己判断返回值类型,并执行响应获取返回值的方法 获取返回值方法只能调用一次,不能多次调用 无法正常的捕获异常 老版浏览器不会默认携带cookie 不支持jsonp 十一、对fetch的封装请求参数处理 支持传入不同的参数类型: function stringify(url, data) { var dataString = url.indexOf('?') == -1 ? '?' : '&'; for (var key in data) { dataString += key + '=' + data[key] + '&'; }; return dataString; } if (request.formData) { request.body = request.data; } else if (/^get$/i.test(request.method)) { request.url = `${request.url}${stringify(request.url, request.data)}`; } else if (request.form) { request.headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8'); request.body = stringify(request.data); } else { request.headers.set('Content-Type', 'application/json;charset=UTF-8'); request.body = JSON.stringify(request.data); } 复制代码cookie携带 fetch在新版浏览器已经开始默认携带同源cookie,但在老版浏览器中不会默认携带,我们需要对他进行统一设置: request.credentials = 'same-origin'; // 同源携带 request.credentials = 'include'; // 可跨域携带 复制代码异常处理 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。 因此我们要对fetch的异常进行统一处理 .then(response =>

{

If (response.ok) {

Return Promise.resolve (response)

} else {

Const error = new Error (`request failed! Status code: ${response.status}, failure message: ${response.statusText} `)

Error.response = response

Return Promise.reject (error)

}

});

Copy code return value processing

Call different functions to receive different return value types. Here, the type must be judged in advance, and the method to obtain the return value cannot be called multiple times:

.then (response = > {

Let contentType = response.headers.get ('content-type')

If (contentType.includes ('application/json')) {

Return response.json ()

} else {

Return response.text ()

}

});

Copy the code jsonp

Fetch itself does not provide support for jsonp, and jsonp itself is not a very good way to solve cross-domain problems. It is recommended to use cors or nginx to solve cross-domain problems. For more information, please see the following section.

Fetch is packaged and can be used happily.

Well, axios works really well.

XII. Cross-domain summary

When it comes to network requests, you have to mention cross-domain.

The browser's same-origin policy limits how documents or scripts loaded from the same source interact with resources from another source. This is an important security mechanism for isolating potentially malicious files. Read operations between different sources are usually not allowed.

Cross-domain conditions: protocols, domain names, ports, there is a difference even if cross-domain.

Here are several ways to solve cross-domain problems:

Nginx

Use nginx reverse proxy to achieve cross-domain, refer to my article: nginx knowledge necessary for front-end developers

Cors

CORS is a W3C standard, the full name is "cross-domain resource sharing" (Cross-origin resource sharing). It allows browsers to make XMLHttpRequest requests to cross-source servers.

CORS can be enabled by setting Access-Control-Allow-Origin on the server. This attribute indicates which domain names can access the resource, and if you set a wildcard, it means that all websites can access the resource.

App.all ('*', function (req, res, next) {

Res.header ("Access-Control-Allow-Origin", "*")

Res.header ("Access-Control-Allow-Headers", "X-Requested-With")

Res.header ("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS")

Next ()

});

Copy the code jsonp

The link in the src attribute of the script tag can access cross-domain js scripts. Using this feature, the server no longer returns data in JSON format, but returns a piece of js code that calls a function, which is called in src.

Jquery support for jsonp:

$.ajax ({

Type: "get"

Url: "http://xxxx"

DataType: "jsonp"

Jsonp: "callback"

JsonpCallback: "doo"

Success: function (data) {

Console.log (data)

}

});

Fetch, axios, etc., do not provide direct support for jsonp. If you need to use this method, you can try manual encapsulation:

(function (window,document) {

"use strict"

Var jsonp = function (url,data,callback) {

/ / 1. Convert the incoming data data to url string form

/ / {id:1,name:'jack'} = > id=1&name=jack

Var dataString = url.indexof ('?') =-1?'?:'&'

For (var key in data) {

DataString + = key +'='+ data [key] +'&'

}

/ / 2 handles the callback function in url

/ / name of the cbFuncName callback function: prefix of my_json_cb_ name + random number (remove the decimal point)

Var cbFuncName = 'my_json_cb_' + Math.random (). ToString (). Replace ('.',')

DataString + = 'callback=' + cbFuncName

/ / 3. Create a script tag and insert it into the page

Var scriptEle = document.createElement ('script')

ScriptEle.src = url + dataString

/ / 4. Mount callback function

Window [cbFuncName] = function (data) {

Callback (data)

/ / delete the script tag of jsonp after processing the data of the callback function

Document.body.removeChild (scriptEle)

}

Document.body.appendChild (scriptEle)

}

Window.$jsonp = jsonp

}) (window,document)

PostMessage cross-domain

The postMessage () method allows scripts from different sources to communicate in a limited way asynchronously, and messages can be delivered across text files, multiple windows, and across domains.

/ / capture iframe

Var domain = 'http://scriptandstyle.com';

Var iframe = document.getElementById ('myIFrame'). ContentWindow

/ / send a message

SetInterval (function () {

Var message = 'Hello! The time is:' + (new Date () .getTime ())

Console.log ('blog.local: sending message:' + message)

/ / send the message and target URI

Iframe.postMessage (message,domain)

}, 6000)

/ / respond to events

Window.addEventListener ('message',function (event) {

If (event.origin! = 'http://davidwalsh.name') return

Console.log ('message received:' + event.data,event)

Event.source.postMessage ('holla back event. Origin)

}, false)

PostMessage is suitable for the following scenarios: cross-domain communication between multiple windows of the same browser, and cross-domain communication between iframe.

WebSocket

WebSocket is a two-way communication protocol. After establishing a connection, both server and client of WebSocket can actively send or receive data to each other without the restriction of the same origin policy.

Function WebSocketTest () {

If ("WebSocket" in window) {

Alert ("your browser supports WebSocket!")

/ / Open a web socket

Var ws = new WebSocket ("ws://localhost:3000/abcd")

Ws.function () {

/ / Web Socket is connected, use the send () method to send data

Ws.send ("send data")

Alert ("data sending...")

}

Ws. (evt) {

Var received_msg = evt.data

Alert ("data received...")

}

Ws.

/ / close websocket

Alert ("connection closed...")

}

} else {

/ / browser does not support WebSocket

Alert ("your browser does not support WebSocket!")

}

}

The above is all the contents of the article "what are the ways in which the front end makes network requests?" Thank you for your reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report