浏览器中xhr选项是做什么用的呢_前端常见面试 - 请求篇

本文探讨了xhr、vue-resource、fetch和axios在前端AJAX请求中的使用,包括xhr的不足、vue-resource的特点、fetch的配置和axios的优势。xhr的异步模型和代码可读性较差,而vue-resource体积小且支持Promise API。fetch基于Promise,但默认不携带cookie。axios是一个强大的HTTP库,支持Promise和拦截器,同时提供了并发请求的功能。在选择这些工具时,应结合业务需求和个人偏好。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缺点:

不符合MVVM

异步模型不够现代,不支持链式,代码可读性差

整个Jquery太大,引入成本过高

当然,我们可以直接使用XMLHttpReqeust来进行实现自己的ajax封装,具体代码如下:

consthttp = {

/**

* js封装ajax请求

* >>使用new 创建请求对象,所以不考虑低端IE浏览器(IE6及以下不支持)

* >>使用es6语法,如果需要在正式环境使用,则可以用babel转换为es5语法 https://babeljs.cn/docs/setup/#installation

* @param settings 请求参数模仿jQuery ajax

* 调用该方法,data参数需要和请求头Content-Type对应

* Content-Type data 描述

* application/x-www-form-urlencoded 'name=哈哈&age=12'或{name:'哈哈',age:12} 查询字符串,用&分割

* application/json name=哈哈&age=12' json字符串

* multipart/form-data new FormData FormData对象,当为FormData类型,不要手动设置Content-Type

* 注意:请求参数如果包含日期类型.是否能请求成功需要后台接口配合

*/

ajax: (settings = {}) => {

// 初始化请求参数

let_s = Object.assign({

url: '', // string

type: 'GET', // string 'GET' 'POST' 'DELETE'

dataType: 'json', // string 期望的返回数据类型:'json' 'text' 'document' ...

async: true, // boolean true:异步请求 false:同步请求 required

data: null, // any 请求参数,data需要和请求头Content-Type对应

headers: {}, // object 请求头

timeout: 1000, // string 超时时间:0表示不设置超时

beforeSend: (xhr) => {

},

success: (result, status, xhr) => {

},

error: (xhr, status, error) => {

},

complete: (xhr, status) => {

}

}, settings);

// 参数验证

if(!_s.url || !_s.type || !_s.dataType || !_s.async) {

alert( '参数有误');

return;

}

// 创建请求对象

letxhr = new;

// 请求开始回调函数

xhr.addEventListener( 'loadstart', e => {

_s.beforeSend(xhr);

});

// 请求成功回调函数

xhr.addEventListener( 'load', e => {

conststatus = xhr.status;

if((status >= 200&& status < 300) || status === 304) {

letresult;

if(xhr.responseType === 'text') {

result = xhr.responseText;

} elseif(xhr.responseType === 'document') {

result = xhr.responseXML;

} else{

result = xhr.response;

}

// 注意:状态码200表示请求发送/接受成功,不表示业务处理成功

_s.success(result, status, xhr);

} else{

_s.error(xhr, status, e);

}

});

// 请求结束

xhr.addEventListener( 'loadend', e => {

_s.complete(xhr, xhr.status);

});

// 请求出错

xhr.addEventListener( 'error', e => {

_s.error(xhr, xhr.status, e);

});

// 请求超时

xhr.addEventListener( 'timeout', e => {

_s.error(xhr, 408, e);

});

letuseUrlParam = false;

letsType = _s.type.toUpperCase;

// 如果是"简单"请求,则把data参数组装在url上

if(sType === 'GET'|| sType === 'DELETE') {

useUrlParam = true;

_s.url += http.getUrlParam(_s.url, _s.data);

}

// 初始化请求

xhr.open(_s.type, _s.url, _s.async);

// 设置期望的返回数据类型

xhr.responseType = _s.dataType;

// 设置请求头

for( constkey of Object.keys(_s.headers)) {

xhr.setRequestHeader(key, _s.headers[key]);

}

// 设置超时时间

if(_s.async && _s.timeout) {

xhr.timeout = _s.timeout;

}

// 发送请求.如果是简单请求,请求参数应为null.否则,请求参数类型需要和请求头Content-Type对应

xhr.send(useUrlParam ? null: http.getQueryData(_s.data));

},

// 把参数data转为url查询参数

getUrlParam: (url, data) => {

if(!data) {

return'';

}

letparamsStr = data instanceofObject? http.getQueryString(data) : data;

return(url.indexOf( '?') !== -1) ? paramsStr : '?'+ paramsStr;

},

// 获取ajax请求参数

getQueryData: (data) => {

if(!data) {

returnnull;

}

if( typeofdata === 'string') {

returndata;

}

if(data instanceofFormData) {

returndata;

}

returnhttp.getQueryString(data);

},

// 把对象转为查询字符串

getQueryString: (data) => {

letparamsArr = [];

if(data instanceofObject) {

Object.keys(data).forEach(key => {

letval = data[key];

// todo 参数Date类型需要根据后台api酌情处理

if(val instanceofDate) {

// val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss');

}

paramsArr.push( encodeURIComponent(key) + '='+ encodeURIComponent(val));

});

}

returnparamsArr.join( '&');

}

}

No.3

vue-resource 请求

vue-resource是Vue.js的一款插件,它可以通过或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。另外,vue-resource还提供了非常有用的inteceptor功能,使用inteceptor可以在请求前和请求后附加一些行为,比如使用inteceptor在ajax请求时显示loading界面。

特点:

1. 体积小

vue-resource 非常小巧,在压缩以后只有大约 12KB,服务端启用 gzip 压缩后只有 4.5KB 大小,这远比 jQuery 的体积要小得多。

2. 支持主流的浏览器

和 Vue.js 一样,vue-resource 除了不支持 IE 9 以下的浏览器,其他主流的浏览器都支持。

3. 支持 Promise API 和 URI Templates

Promise 是 ES6 的特性,Promise 的中文含义为“先知”,Promise 对象用于异步计算。

URI Templates 表示 URI 模板,有些类似于 ASP.NET MVC 的路由模板。

4. 支持拦截器

拦截器是全局的,拦截器可以在请求发送前和发送请求后做一些处理。

拦截器在一些场景下会非常有用,比如请求发送前在 headers 中设置 access_token,或者在请求失败时,提供共通的处理方式。

常用api

get(url, [options])

head(url, [options])

delete(url, [options])

jsonp(url, [options])

post(url, [body], [options])

put(url, [body], [options])

patch(url, [body], [options])

option 详解

No.4

fetch

1.fetch是基于promise实现的,也可以结合async/await

2.fetch请求默认是不带cookie的,需要设置fetch(URL,{credentials:’include’})。

3. Credentials 有三种参数:same-origin,include,*

4. 服务器返回 400 500 状态码时并不会reject,只有网络出错导致请求不能完成时,fetch才会被reject

5. 所有版本的 IE 均不支持原生Fetch

6.fetch是widow的一个方法

fetch(url). then( function(response) {

returnresponse.json;

}). then( function(data) {

console. log(data);

}). catch( function(e) {

console. log( "Oops, error");

});

可配合 es6 的箭头函数进行使用

fetch(url).then(response => response.json)

.then(data => console.log(data))

.catch(e => console.log( "Oops, error", e))

No.5

axios

Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中

特点:

从浏览器中创建s

从node.js创建http请求

支持PromiseAPI

拦截请求和响应

转换请求数据和响应数据

取消请求

自动转换JSON数据

客户端支持防御XSRF常用 api:

axios.request(config)

axios.get(url[, config])

axios.delete(url[, config])

axios.head(url[, config])

axios.options(url[, config])

axios.post(url[, data[, config]])

axios.put(url[, data[, config]])

axios.patch(url[, data[, config]]

实例:

get 请求

// 为给定 ID 的 user 创建请求

axios.get( '/user?ID=12345')

. then( function(response) {

console. log(response);

})

. catch( function(error) {

console. log( error);

});

// 可选地,上面的请求可以这样做

axios.get( '/user', {

params: {

ID: 12345

}

})

. then( function(response) {

console. log(response);

})

. catch( function(error) {

console. log( error);

});

post 请求

axios.post( '/user', {

firstName: 'Fred',

lastName: 'Flintstone'

})

. then( function(response) {

console. log(response);

})

. catch( function(error) {

console. log( error);

});

并发请求

functiongetUserAccount{

returnaxios.get('/user/12345');

}

functiongetUserPermissions{

returnaxios.get('/user/12345/permissions');

}

axios. all([getUserAccount, getUserPermissions])

. then(axios.spread( function(acct, perms) {

// 两个请求现在都执行完成

}));

拦截器

// 添加请求拦截器

axios.interceptors.request.use( function(config) {

// 在发送请求之前做些什么

returnconfig;

}, function(error) {

// 对请求错误做些什么

returnPromise.reject(error);

});

// 添加响应拦截器

axios.interceptors.response.use( function(response) {

// 对响应数据做点什么

returnresponse;

}, function(error) {

// 对响应错误做点什么

returnPromise.reject(error);

});

取消请求

varCancelToken = axios.CancelToken;

varsource = CancelToken.source;

axios. get( '/user/12345', {

cancelToken: source.token

}). catch( function(thrown) {

if(axios.isCancel(thrown)) {

console.log( 'Request canceled', thrown.message);

} else{

// 处理错误

}

});

// 取消请求(message 参数是可选的)

source.cancel( 'Operation canceled by the user.');

当然,无论选择哪一种方式都需要自身结合业务的需要和自我的认知,没有哪个绝对的优秀,也没有哪个绝对不优秀。

SegmentFault 思否社区和文章作者展开更多互动和交流。返回搜狐,查看更多

### 手写 AJAX 的实现 AJAX 是一种用于在后台与服务器交换数据的技术,它允许网页不重新加载的情况下更新部分内容。以下是基于 XMLHttpRequest 对象的手写 AJAX 实现代码: ```javascript function createXHR() { if (typeof XMLHttpRequest !== 'undefined') { return new XMLHttpRequest(); // 大部分现代浏览器支持此方式 } else if (typeof ActiveXObject !== 'undefined') { // 兼容旧版 IE 浏览器 const versions = ['MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'Microsoft.XMLHTTP']; for (let i = 0, len = versions.length; i < len; ++i) { try { return new ActiveXObject(versions[i]); } catch (e) {} } } } function ajax(options) { options = options || {}; options.method = (options.method || 'GET').toUpperCase(); options.url = options.url || ''; options.async = options.async === undefined ? true : !!options.async; options.data = options.data || null; const xhr = createXHR(); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && ((options.type === 'json' && xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)) { if (options.success) { if (options.type === 'json') { options.success(JSON.parse(xhr.responseText)); // 解析 JSON 数据 } else { options.success(xhr.responseText); // 返回纯文本数据 } } } }; let params = []; if (options.data && typeof options.data === 'object') { Object.keys(options.data).forEach(function (key) { params.push(key + '=' + encodeURIComponent(options.data[key])); }); } if (options.method === 'POST') { xhr.open(options.method, options.url, options.async); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send(params.join('&')); } else if (options.method === 'GET') { if (params.length > 0) { options.url += '?' + params.join('&'); } xhr.open(options.method, options.url, options.async); xhr.send(null); } } ``` #### 使用示例 以下是一个调用 `ajax` 函数的例子: ```javascript ajax({ method: 'GET', url: '/api/data', async: true, success: function (response) { console.log(response); // 输出返回的数据 }, type: 'json' }); ``` --- ### 关键点解析 1. **创建 XHR 对象** 创建 XMLHttpRequest 或兼容旧版本 IE 的 ActiveXObject[^1]。 2. **设置请求方法和 URL** 支持 GET 和 POST 请求方法,并处理参数拼接逻辑[^2]。 3. **异步操作** 默认情况下,AJAX 请求是异步的 (`async=true`)。可以通过配置选项更改该行为[^3]。 4. **错误处理** 当前未包含详细的错误处理机制,实际开发中应加入对网络异常、超时等情况的捕获[^4]。 5. **JSON 数据解析** 如果响应类型为 JSON,则通过 `JSON.parse()` 方法将其转换为 JavaScript 对象[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值