在XMLHttpRequest
出现之前,如果服务端数据有更新,需要重新刷新整个页面。XMLHttpRequest
提供了从web服务器
获取数据的能力,如果想要更新某条数据,只需要通过XMLHttpRequest
请求服务器通过的接口就可以获取到服务端的数据,然后操作dom
来更新页面内容,整个过程只需要更新页面的一部分就可以了。
同步回调和异步回调
什么是回调函数
将一个函数作为参数传递给另一个函数,作为参数的这个函数就是回调函数
js
function cb() {
console.log('i am callback');
}
function main(cb) {
console.log('start execute main');
cb();
}
main();
回调函数分为同步回调和异步回调
- 同步回调: 是指回调函数会立即执行,而不会等待异步操作完成或特定事件发生。在同步回调中,回调函数在调用它的函数执行期间同步地执行,而不会被放入事件队列中等待执行。
js
// 同步回调函数
function syncCallback(callback) {
console.log('Start of syncCallback');
callback(); // 同步调用回调函数
console.log('End of syncCallback');
}
// 调用同步回调函数,并传递一个回调函数
syncCallback(function () {
console.log('Inside callback');
});
console.log('After syncCallback');
// 输出顺序
// Start of syncCallback
// Inside callback
// End of syncCallback
// After syncCallback
同步回调函数的执行是立即发生的,它会阻塞后续代码的执行,直到回调函数执行完成。这与异步回调不同,后者会将回调函数放入事件队列中,在合适的时机执行。
- 异步回调: 是指回调函数不会立即执行,而是会在将来的某个时间点执行,通常是在异步操作完成或特定事件发生时。
js
// 异步回调函数模拟从服务器获取数据
function fetchDataFromServer(callback) {
console.log('Start of fetchDataFromServer');
// 模拟异步操作,例如 AJAX 请求
setTimeout(() => {
const data = 'Data from server';
console.log('Async operation completed');
// 调用回调函数,并将获取的数据传递给它
callback(data);
}, 2000); // 模拟2秒延迟
console.log('End of fetchDataFromServer');
}
// 调用异步回调函数,并传递一个回调函数
fetchDataFromServer(function processData(data) {
console.log('Received data:', data);
});
console.log('After fetchDataFromServer');
// 输出顺序
// Start of fetchDataFromServer
// End of fetchDataFromServer
// After fetchDataFromServer
// Async operation completed
// Received data: Data from server
在异步回调中,回调函数的执行被推迟到异步操作完成后,使得程序能够继续执行其他代码而不被阻塞。
XMLHttpRequest的运作机制
- 创建 XMLHttpRequest 对象: 使用
new XMLHttpRequest()
创建一个XMLHttpRequest
对象。
js
const var xhr = new XMLHttpRequest();
- 设置请求参数: 使用
open
方法设置请求的类型(GET、POST
等)和请求的URL
。
js
xhr.open('GET', 'https://api.example.com/data', true);
arduino
第一个参数:HTTP 请求的方法,例如 'GET' 或 'POST'。
第二个参数:请求的 URL。
第三个参数:是否使用异步请求(通常设置为 true)
- 设置请求头(可选): 使用
setRequestHeader
方法设置HTTP
请求头信息。
js
xhr.setRequestHeader('Content-Type', 'application/json');
这一步通常在发送 POST
请求时设置请求头。
- 设置回调函数: 使用
onreadystatechange
事件处理程序设置状态变化时的回调函数。
js
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// 请求完成,并且响应状态为 200(OK)
console.log('Response:', xhr.responseText);
}
};
lua
readyState 属性表示请求的状态,4 表示请求已完成。
status 属性表示响应的 HTTP 状态码,200 表示成功。
- 发送请求: 使用
send
方法发送HTTP
请求。
js
xhr.send();
对于 POST
请求,可以将数据作为参数传递给 send
方法。
js
javascriptCopy codevar data = { key: 'value' };
xhr.send(JSON.stringify(data));
完整的示例代码:
js
// 简单的 GET 请求的示例
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('Response:', xhr.responseText);
}
};
xhr.send();
使用XMLHttpRequest容易出现的问题
同源策略: XMLHttpRequest
遵循同源策略,即默认情况下,只能向与包含该脚本的文档同源的 URL
发送请求。跨域请求可能会受到浏览器的限制。
- CORS(跨域资源共享): 如果要向不同源的服务器发送请求,服务器需要支持跨域资源共享(
CORS
)。在这种情况下,服务器需要设置合适的响应头,客户端代码也需要处理CORS
相关的配置。 - 安全性:
XMLHttpRequest
受浏览器的安全性限制,一些操作可能受到限制,例如访问本地文件系统。 - 异步和同步请求: 默认情况下,
XMLHttpRequest
是异步的,如果需要同步请求,可能会导致界面被冻结,用户体验下降。同步请求在大多数情况下都不推荐使用。 - 浏览器兼容性: 虽然
XMLHttpRequest
是标准的Web API
,但在旧版的Internet Explorer
中可能存在一些兼容性问题。在现代Web
开发中,使用Fetch API
更为推荐。 - 错误处理: 需要注意对请求错误的适当处理,例如网络错误、服务器错误等。使用
onerror
和onreadystatechange
事件来捕获和处理这些错误。 - 同一资源多次请求: 如果相同的资源(例如图片或脚本)被多次请求,可能会导致性能问题。浏览器通常会对相同的资源进行缓存,以减少不必要的网络请求。
- 可维护性: 使用
XMLHttpRequest
的代码可能会变得复杂和难以维护,特别是在处理多个异步请求时。考虑使用Promise
或async/await
来改善代码的可读性和可维护性。
HTTPS混合内容问题
混合内容(Mixed Content) 是指网页同时包含了通过安全 HTTPS
和不安全 HTTP
协议加载的内容。这可能会导致安全性问题,因为不安全的 HTTP
请求可能被攻击者窃听或篡改。HTTPS
页面应该只加载通过安全协议传输的内容,以确保页面的整体安全性。
混合内容分为两种类型:
- 混合主动内容(Mixed Active Content): 这是指通过不安全的
HTTP
协议加载的脚本、样式表、图片等主动执行的资源。例如,通过标签 <img> 引入的 HTTP 脚本。 - 混合被动内容(Mixed Passive Content): 这是指通过不安全的 HTTP 协议加载的图片、音频、视频等被动的资源。例如,通过 <img> 引入的 HTTP 图片。
问题和风险:
-
安全性问题:不安全的
HTTP
请求可能会被中间人攻击拦截、窃听或篡改,导致安全风险。 -
浏览器警告:现代浏览器通常会在包含混合内容的
HTTPS
页面上显示警告,提醒用户存在安全风险。
解决混合内容问题的方法:
- 使用 HTTPS 加载所有内容: 将所有页面上的资源都通过
HTTPS
加载,包括脚本、样式表、图片等。确保网站上的所有资源都通过安全的协议传输。 - 升级 HTTP 资源: 如果某些资源无法通过
HTTPS
加载,尝试将这些资源升级为支持HTTPS
的版本。许多服务提供商都提供了通过 HTTPS 访问的资源。 - 子资源完整性(Subresource Integrity,SRI): 对于无法升级为
HTTPS
的资源,可以使用SRI
来确保资源的完整性。SRI
允许您在引入脚本或样式表时提供一个哈希值,浏览器将检查资源的哈希是否匹配。 - Content Security Policy(CSP): 使用
CSP 头
来限制网页加载的内容来源,阻止加载不安全的内容。通过CSP
可以配置白名单,指定允许加载的内容来源。
txt
Content-Security-Policy: upgrade-insecure-requests;
- 更新引用: 定期检查网站的引用,确保所有资源的引用都使用了正确的协议。