我如何承诺原生 XHR?
How do I promisify native XHR?
我想在我的前端应用程序中使用(本机)promises 来执行 XHR 请求,但没有大型框架的所有 tomfooly。
我想让我的 xhr return 一个承诺,但这行不通(给我:Uncaught TypeError: Promise resolver undefined is not a function
)
function makeXHRRequest (method, url, done) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function() { return new Promise().resolve(); };
xhr.onerror = function() { return new Promise().reject(); };
xhr.send();
}
makeXHRRequest('GET', 'http://example.com')
.then(function (datums) {
console.log(datums);
});
我假设你知道如何发出原生 XHR 请求(你可以复习一下 here and here)
因为 any browser that supports native promises 也将支持 xhr.onload
,我们可以跳过所有 onReadyStateChange
的愚蠢行为。让我们退后一步,从使用回调的基本 XHR 请求函数开始:
function makeRequest (method, url, done) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
done(null, xhr.response);
};
xhr.onerror = function () {
done(xhr.response);
};
xhr.send();
}
// And we'd call it as such:
makeRequest('GET', 'http://example.com', function (err, datums) {
if (err) { throw err; }
console.log(datums);
});
万岁!这不涉及任何非常复杂的事情(比如自定义 headers 或 POST 数据),但足以让我们继续前进。
promise 构造函数
我们可以像这样构建一个承诺:
new Promise(function (resolve, reject) {
// Do some Async stuff
// call resolve if it succeeded
// reject if it failed
});
promise 构造函数接受一个函数,该函数将传递两个参数(我们称它们为 resolve
和 reject
)。您可以将这些视为回调,一个用于成功,一个用于失败。例子很棒,让我们用这个构造函数更新 makeRequest
:
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject({
status: xhr.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: xhr.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
// Example:
makeRequest('GET', 'http://example.com')
.then(function (datums) {
console.log(datums);
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
现在我们可以利用 promises 的力量,链接多个 XHR 调用(并且 .catch
将在任一调用中触发错误):
makeRequest('GET', 'http://example.com')
.then(function (datums) {
return makeRequest('GET', datums.url);
})
.then(function (moreDatums) {
console.log(moreDatums);
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
我们可以进一步改进,添加 POST/PUT 参数和自定义 headers。让我们使用一个选项 object 而不是多个参数,签名为:
{
method: String,
url: String,
params: String | Object,
headers: Object
}
makeRequest
现在看起来像这样:
function makeRequest (opts) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(opts.method, opts.url);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject({
status: xhr.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: xhr.status,
statusText: xhr.statusText
});
};
if (opts.headers) {
Object.keys(opts.headers).forEach(function (key) {
xhr.setRequestHeader(key, opts.headers[key]);
});
}
var params = opts.params;
// We'll need to stringify if we've been given an object
// If we have a string, this is skipped.
if (params && typeof params === 'object') {
params = Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
}
xhr.send(params);
});
}
// Headers and params are optional
makeRequest({
method: 'GET',
url: 'http://example.com'
})
.then(function (datums) {
return makeRequest({
method: 'POST',
url: datums.url,
params: {
score: 9001
},
headers: {
'X-Subliminal-Message': 'Upvote-this-answer'
}
});
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
可以在 MDN 找到更全面的方法。
这可以像下面的代码一样简单。
请记住,此代码只会在调用 onerror
时触发 reject
回调(仅限 network 错误),而不是在 HTTP 状态时代码表示错误。这也将排除所有其他例外情况。处理这些应该取决于你,IMO。
此外,建议使用 Error
的实例而不是事件本身调用 reject
回调,但为了简单起见,我保持原样。
function request(method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = resolve;
xhr.onerror = reject;
xhr.send();
});
}
调用它可能是这样的:
request('GET', 'http://google.com')
.then(function (e) {
console.log(e.target.response);
}, function (e) {
// handle errors
});
对于现在搜索此内容的任何人,您可以使用 fetch 功能。
它有一些相当不错 support.
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
我首先使用了@SomeKittens 的答案,但后来发现 fetch
开箱即用:)
我认为我们可以通过不创建 XMLHttpRequest
object 来使 the top answer 更加灵活和可重用。这样做的唯一好处是我们不必自己编写 2 或 3 行代码来完成它,而且它有一个巨大的缺点,那就是剥夺了我们对 API 的许多功能的访问权限,比如设置 headers。它还从应该处理响应(成功和错误)的代码中隐藏了原始 object 的属性。因此,我们可以通过仅接受 XMLHttpRequest
object 作为 input 并将其作为 result.
此函数将任意 XMLHttpRequest
object 转换为承诺,默认将非 200 状态代码视为错误:
function promiseResponse(xhr, failNon2xx = true) {
return new Promise(function (resolve, reject) {
// Note that when we call reject, we pass an object
// with the request as a property. This makes it easy for
// catch blocks to distinguish errors arising here
// from errors arising elsewhere. Suggestions on a
// cleaner way to allow that are welcome.
xhr.onload = function () {
if (failNon2xx && (xhr.status < 200 || xhr.status >= 300)) {
reject({request: xhr});
} else {
resolve(xhr);
}
};
xhr.onerror = function () {
reject({request: xhr});
};
xhr.send();
});
}
这个函数很自然地适合 Promise
链,而不会牺牲 XMLHttpRequest
API:
的灵活性
Promise.resolve()
.then(function() {
// We make this a separate function to avoid
// polluting the calling scope.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://whosebug.com/');
return xhr;
})
.then(promiseResponse)
.then(function(request) {
console.log('Success');
console.log(request.status + ' ' + request.statusText);
});
上面省略了 catch
以使示例代码更简单。你应该总是有一个,当然我们可以:
Promise.resolve()
.then(function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://whosebug.com/doesnotexist');
return xhr;
})
.then(promiseResponse)
.catch(function(err) {
console.log('Error');
if (err.hasOwnProperty('request')) {
console.error(err.request.status + ' ' + err.request.statusText);
}
else {
console.error(err);
}
});
并且禁用 HTTP 状态代码处理不需要对代码进行太多更改:
Promise.resolve()
.then(function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://whosebug.com/doesnotexist');
return xhr;
})
.then(function(xhr) { return promiseResponse(xhr, false); })
.then(function(request) {
console.log('Done');
console.log(request.status + ' ' + request.statusText);
});
我们的调用代码比较长,但是从概念上来说,理解起来还是很简单的。而且我们不必为了支持其功能而重建整个 Web 请求 API。
我们还可以添加一些方便的函数来整理我们的代码:
function makeSimpleGet(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
return xhr;
}
function promiseResponseAnyCode(xhr) {
return promiseResponse(xhr, false);
}
那么我们的代码就变成了:
Promise.resolve(makeSimpleGet('https://whosebug.com/doesnotexist'))
.then(promiseResponseAnyCode)
.then(function(request) {
console.log('Done');
console.log(request.status + ' ' + request.statusText);
});
jpmc26 的回答在我看来非常接近完美。不过,它有一些缺点:
- 它只在最后一刻公开 xhr 请求。这不允许
POST
-requests设置请求体。
- 由于关键的
send
调用隐藏在函数中,因此更难阅读。
- 它在实际发出请求时引入了相当多的样板文件。
Monkey 修补 xhr 对象解决了这些问题:
function promisify(xhr, failNon2xx=true) {
const oldSend = xhr.send;
xhr.send = function() {
const xhrArguments = arguments;
return new Promise(function (resolve, reject) {
// Note that when we call reject, we pass an object
// with the request as a property. This makes it easy for
// catch blocks to distinguish errors arising here
// from errors arising elsewhere. Suggestions on a
// cleaner way to allow that are welcome.
xhr.onload = function () {
if (failNon2xx && (xhr.status < 200 || xhr.status >= 300)) {
reject({request: xhr});
} else {
resolve(xhr);
}
};
xhr.onerror = function () {
reject({request: xhr});
};
oldSend.apply(xhr, xhrArguments);
});
}
}
现在的用法很简单:
let xhr = new XMLHttpRequest()
promisify(xhr);
xhr.open('POST', 'url')
xhr.setRequestHeader('Some-Header', 'Some-Value')
xhr.send(resource).
then(() => alert('All done.'),
() => alert('An error occured.'));
当然,这会带来另一个缺点:猴子修补确实会影响性能。然而,假设用户主要在等待 xhr 的结果,请求本身比设置调用要长几个数量级,并且 xhr 请求不经常发送,这应该不是问题。
PS:当然,如果针对现代浏览器,请使用 fetch!
PPS:评论中已经指出,此方法改变了标准API,这可能会造成混淆。为了更清楚起见,可以将一种不同的方法修补到 xhr 对象 sendAndGetPromise()
.
如果您希望您的代码在旧浏览器中工作,请将其放在 HTML 文档的
中:
<script>
self.Promise||document.write("<script src=/path/to/promise/polyfill.js><\/script>");
</script>
将 /path/to/promise/polyfill.js 替换为您的 Promise polyfill 的路径。如果 class 不是原生的,这将创建一个 Promise class,并允许您的代码在旧浏览器(如 Internet Explorer)上 运行。 Internet Explorer 和其他老式浏览器占市场份额的一小部分,看似微不足道,但这仍然转化为数百万用户,因此我不建议完全放弃这些用户。
我可以推荐这个 Promise polyfill:
https://github.com/stefanpenner/es6-promise/
现在您可以访问 Promise class。
如果您希望您的代码在 IE 6-8 等非常旧的浏览器中工作,您需要使用 onreadystatechange 而不是 onload。这没有什么坏处,因为 onreadystatechange 仍然在所有当前浏览器中使用以实现向后兼容性:
function send_request(xhr, data, timeout) {
return new Promise(function (resolve, reject) {
var s, p, i;
if (data && data.constructor==Object) {// serialize object
s = "_="+(new Date).getTime();
for (p in data) if (data.hasOwnProperty(p)) {
if (!data[p] || data[p].constructor!=Array) {
data[p] = [data[p]]
}
for (i=0; i<data[p].length; i++) {
s+= "&"+encodeuricomponent(p)+"="+encodeuricomponent(data[p][i]);
}
}
data = s;
}
xhr.onreadystatechange = function() {
if (xhr.readyState==4) {
resolve(xhr);
}
}
xhr.send(data);
if (timeout) {
settimeout(function() {
reject("timeout");
xhr.abort();
}, timeout);// milliseconds until timeout
}
});
}
xhr = new XMLHttpRequest();
xhr.open("GET", "/some/file", true);
send_request(xhr).then(function(xhr) {
if (xhr.status>=200 || xhr.status<400) {
//success
alert(xhr.responseText);
}
else {
return Promise.reject(xhr.statusText? xhr.status+" "+xhr.statusText: "error");
}
})
请记住,IE 6 不支持 XMLHttpRequest,因此您还需要对其进行 polyfill,而您可以使用 ActiveX 来完成。您的文档
中类似以下内容的内容可能有效:
<!--[if lt IE 7]>
<script>
// This is just an example. Use at your own risk.
function XMLHttpRequest() {
try {
return new ActiveXObject("Msxml2.XMLHTTP.6.0")
}
catch (e) {
return new ActiveXObject("Msxml2.XMLHTTP.3.0")
}
}
</script>
<![endif]-->
我想在我的前端应用程序中使用(本机)promises 来执行 XHR 请求,但没有大型框架的所有 tomfooly。
我想让我的 xhr return 一个承诺,但这行不通(给我:Uncaught TypeError: Promise resolver undefined is not a function
)
function makeXHRRequest (method, url, done) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function() { return new Promise().resolve(); };
xhr.onerror = function() { return new Promise().reject(); };
xhr.send();
}
makeXHRRequest('GET', 'http://example.com')
.then(function (datums) {
console.log(datums);
});
我假设你知道如何发出原生 XHR 请求(你可以复习一下 here and here)
因为 any browser that supports native promises 也将支持 xhr.onload
,我们可以跳过所有 onReadyStateChange
的愚蠢行为。让我们退后一步,从使用回调的基本 XHR 请求函数开始:
function makeRequest (method, url, done) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
done(null, xhr.response);
};
xhr.onerror = function () {
done(xhr.response);
};
xhr.send();
}
// And we'd call it as such:
makeRequest('GET', 'http://example.com', function (err, datums) {
if (err) { throw err; }
console.log(datums);
});
万岁!这不涉及任何非常复杂的事情(比如自定义 headers 或 POST 数据),但足以让我们继续前进。
promise 构造函数
我们可以像这样构建一个承诺:
new Promise(function (resolve, reject) {
// Do some Async stuff
// call resolve if it succeeded
// reject if it failed
});
promise 构造函数接受一个函数,该函数将传递两个参数(我们称它们为 resolve
和 reject
)。您可以将这些视为回调,一个用于成功,一个用于失败。例子很棒,让我们用这个构造函数更新 makeRequest
:
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject({
status: xhr.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: xhr.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
// Example:
makeRequest('GET', 'http://example.com')
.then(function (datums) {
console.log(datums);
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
现在我们可以利用 promises 的力量,链接多个 XHR 调用(并且 .catch
将在任一调用中触发错误):
makeRequest('GET', 'http://example.com')
.then(function (datums) {
return makeRequest('GET', datums.url);
})
.then(function (moreDatums) {
console.log(moreDatums);
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
我们可以进一步改进,添加 POST/PUT 参数和自定义 headers。让我们使用一个选项 object 而不是多个参数,签名为:
{
method: String,
url: String,
params: String | Object,
headers: Object
}
makeRequest
现在看起来像这样:
function makeRequest (opts) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(opts.method, opts.url);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject({
status: xhr.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: xhr.status,
statusText: xhr.statusText
});
};
if (opts.headers) {
Object.keys(opts.headers).forEach(function (key) {
xhr.setRequestHeader(key, opts.headers[key]);
});
}
var params = opts.params;
// We'll need to stringify if we've been given an object
// If we have a string, this is skipped.
if (params && typeof params === 'object') {
params = Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
}
xhr.send(params);
});
}
// Headers and params are optional
makeRequest({
method: 'GET',
url: 'http://example.com'
})
.then(function (datums) {
return makeRequest({
method: 'POST',
url: datums.url,
params: {
score: 9001
},
headers: {
'X-Subliminal-Message': 'Upvote-this-answer'
}
});
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
可以在 MDN 找到更全面的方法。
这可以像下面的代码一样简单。
请记住,此代码只会在调用 onerror
时触发 reject
回调(仅限 network 错误),而不是在 HTTP 状态时代码表示错误。这也将排除所有其他例外情况。处理这些应该取决于你,IMO。
此外,建议使用 Error
的实例而不是事件本身调用 reject
回调,但为了简单起见,我保持原样。
function request(method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = resolve;
xhr.onerror = reject;
xhr.send();
});
}
调用它可能是这样的:
request('GET', 'http://google.com')
.then(function (e) {
console.log(e.target.response);
}, function (e) {
// handle errors
});
对于现在搜索此内容的任何人,您可以使用 fetch 功能。 它有一些相当不错 support.
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
我首先使用了@SomeKittens 的答案,但后来发现 fetch
开箱即用:)
我认为我们可以通过不创建 XMLHttpRequest
object 来使 the top answer 更加灵活和可重用。这样做的唯一好处是我们不必自己编写 2 或 3 行代码来完成它,而且它有一个巨大的缺点,那就是剥夺了我们对 API 的许多功能的访问权限,比如设置 headers。它还从应该处理响应(成功和错误)的代码中隐藏了原始 object 的属性。因此,我们可以通过仅接受 XMLHttpRequest
object 作为 input 并将其作为 result.
此函数将任意 XMLHttpRequest
object 转换为承诺,默认将非 200 状态代码视为错误:
function promiseResponse(xhr, failNon2xx = true) {
return new Promise(function (resolve, reject) {
// Note that when we call reject, we pass an object
// with the request as a property. This makes it easy for
// catch blocks to distinguish errors arising here
// from errors arising elsewhere. Suggestions on a
// cleaner way to allow that are welcome.
xhr.onload = function () {
if (failNon2xx && (xhr.status < 200 || xhr.status >= 300)) {
reject({request: xhr});
} else {
resolve(xhr);
}
};
xhr.onerror = function () {
reject({request: xhr});
};
xhr.send();
});
}
这个函数很自然地适合 Promise
链,而不会牺牲 XMLHttpRequest
API:
Promise.resolve()
.then(function() {
// We make this a separate function to avoid
// polluting the calling scope.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://whosebug.com/');
return xhr;
})
.then(promiseResponse)
.then(function(request) {
console.log('Success');
console.log(request.status + ' ' + request.statusText);
});
上面省略了 catch
以使示例代码更简单。你应该总是有一个,当然我们可以:
Promise.resolve()
.then(function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://whosebug.com/doesnotexist');
return xhr;
})
.then(promiseResponse)
.catch(function(err) {
console.log('Error');
if (err.hasOwnProperty('request')) {
console.error(err.request.status + ' ' + err.request.statusText);
}
else {
console.error(err);
}
});
并且禁用 HTTP 状态代码处理不需要对代码进行太多更改:
Promise.resolve()
.then(function() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://whosebug.com/doesnotexist');
return xhr;
})
.then(function(xhr) { return promiseResponse(xhr, false); })
.then(function(request) {
console.log('Done');
console.log(request.status + ' ' + request.statusText);
});
我们的调用代码比较长,但是从概念上来说,理解起来还是很简单的。而且我们不必为了支持其功能而重建整个 Web 请求 API。
我们还可以添加一些方便的函数来整理我们的代码:
function makeSimpleGet(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
return xhr;
}
function promiseResponseAnyCode(xhr) {
return promiseResponse(xhr, false);
}
那么我们的代码就变成了:
Promise.resolve(makeSimpleGet('https://whosebug.com/doesnotexist'))
.then(promiseResponseAnyCode)
.then(function(request) {
console.log('Done');
console.log(request.status + ' ' + request.statusText);
});
jpmc26 的回答在我看来非常接近完美。不过,它有一些缺点:
- 它只在最后一刻公开 xhr 请求。这不允许
POST
-requests设置请求体。 - 由于关键的
send
调用隐藏在函数中,因此更难阅读。 - 它在实际发出请求时引入了相当多的样板文件。
Monkey 修补 xhr 对象解决了这些问题:
function promisify(xhr, failNon2xx=true) {
const oldSend = xhr.send;
xhr.send = function() {
const xhrArguments = arguments;
return new Promise(function (resolve, reject) {
// Note that when we call reject, we pass an object
// with the request as a property. This makes it easy for
// catch blocks to distinguish errors arising here
// from errors arising elsewhere. Suggestions on a
// cleaner way to allow that are welcome.
xhr.onload = function () {
if (failNon2xx && (xhr.status < 200 || xhr.status >= 300)) {
reject({request: xhr});
} else {
resolve(xhr);
}
};
xhr.onerror = function () {
reject({request: xhr});
};
oldSend.apply(xhr, xhrArguments);
});
}
}
现在的用法很简单:
let xhr = new XMLHttpRequest()
promisify(xhr);
xhr.open('POST', 'url')
xhr.setRequestHeader('Some-Header', 'Some-Value')
xhr.send(resource).
then(() => alert('All done.'),
() => alert('An error occured.'));
当然,这会带来另一个缺点:猴子修补确实会影响性能。然而,假设用户主要在等待 xhr 的结果,请求本身比设置调用要长几个数量级,并且 xhr 请求不经常发送,这应该不是问题。
PS:当然,如果针对现代浏览器,请使用 fetch!
PPS:评论中已经指出,此方法改变了标准API,这可能会造成混淆。为了更清楚起见,可以将一种不同的方法修补到 xhr 对象 sendAndGetPromise()
.
如果您希望您的代码在旧浏览器中工作,请将其放在 HTML 文档的
中:<script>
self.Promise||document.write("<script src=/path/to/promise/polyfill.js><\/script>");
</script>
将 /path/to/promise/polyfill.js 替换为您的 Promise polyfill 的路径。如果 class 不是原生的,这将创建一个 Promise class,并允许您的代码在旧浏览器(如 Internet Explorer)上 运行。 Internet Explorer 和其他老式浏览器占市场份额的一小部分,看似微不足道,但这仍然转化为数百万用户,因此我不建议完全放弃这些用户。
我可以推荐这个 Promise polyfill:
https://github.com/stefanpenner/es6-promise/
现在您可以访问 Promise class。
如果您希望您的代码在 IE 6-8 等非常旧的浏览器中工作,您需要使用 onreadystatechange 而不是 onload。这没有什么坏处,因为 onreadystatechange 仍然在所有当前浏览器中使用以实现向后兼容性:
function send_request(xhr, data, timeout) {
return new Promise(function (resolve, reject) {
var s, p, i;
if (data && data.constructor==Object) {// serialize object
s = "_="+(new Date).getTime();
for (p in data) if (data.hasOwnProperty(p)) {
if (!data[p] || data[p].constructor!=Array) {
data[p] = [data[p]]
}
for (i=0; i<data[p].length; i++) {
s+= "&"+encodeuricomponent(p)+"="+encodeuricomponent(data[p][i]);
}
}
data = s;
}
xhr.onreadystatechange = function() {
if (xhr.readyState==4) {
resolve(xhr);
}
}
xhr.send(data);
if (timeout) {
settimeout(function() {
reject("timeout");
xhr.abort();
}, timeout);// milliseconds until timeout
}
});
}
xhr = new XMLHttpRequest();
xhr.open("GET", "/some/file", true);
send_request(xhr).then(function(xhr) {
if (xhr.status>=200 || xhr.status<400) {
//success
alert(xhr.responseText);
}
else {
return Promise.reject(xhr.statusText? xhr.status+" "+xhr.statusText: "error");
}
})
请记住,IE 6 不支持 XMLHttpRequest,因此您还需要对其进行 polyfill,而您可以使用 ActiveX 来完成。您的文档
中类似以下内容的内容可能有效:<!--[if lt IE 7]>
<script>
// This is just an example. Use at your own risk.
function XMLHttpRequest() {
try {
return new ActiveXObject("Msxml2.XMLHTTP.6.0")
}
catch (e) {
return new ActiveXObject("Msxml2.XMLHTTP.3.0")
}
}
</script>
<![endif]-->