快速了解JavaScript的Ajax

Windows 下安装 ros2 的超详细教程 Windows11 ROS安装 阅读详情

概述

Ajax(Asynchronous JavaScript and XML,即异步 JavaScript 和 XML)技术用于与服务器交换数据并刷新部分页面,实现更好的用户体验。

Ajax 的核心对象是 XMLHttpRequest,通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。由微软实现并在 IE5 中支持,用于执行异步网络请求。虽然 Ajax 是 Asynchronous JavaScript+XML的缩写,但Ajax通信与数据格式无关,并不一定是XML格式。甚至支持 HTTP 以外的协议(如 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制。

使用 Ajax 需要几个步骤:

  1. 创建 XMLHttpRequest 对象。
  2. 发出 HTTP 请求。
  3. 接收服务器传回的数据。
  4. 更新网页数据。

总之,Ajax 就是通过 XMLHttpRequest 对象发出 HTTP 请求,得到服务器响应并处理。

创建 XMLHttpRequest

在所有现代浏览器都可以通过 XMLHttpRequest 构造函数创建对象:

let xhr = new XMLHttpRequest();

而在老版本 IE5 和 IE6 中使用 ActiveX 对象创建:

let xhr = new ActiveXObject("Microsoft.XMLHTTP");

使用 XMLHttpRequest

创建对象后,需要使用 XMLHttpRequest 对象调用 open(type, url, async) 方法并设置三个参数:

  • type:表示请求类型,如 "get" 、"post" 等。
  • url:表示请求的url。
  • async:表示请求是否异步。如 true表示异步请求,false表示同步请求,它会使JavaScript代码等待服务器响应之后在继续执行。

请求

XMLHttpRequest 使用 open() 方法初始化一个请求,一共可以接收五个参数:

open(method, url, async, username, password): void;
  • method:字符串,表示要传入的HTTP方法,如/GET/POST/PUT/DELETE等。
  • url:字符串,表示请求发送目标URL。
  • async:布尔值,表示请求是否为异步,默认为true。如果值为false,send()方法只有等待收到服务器返回结果,才会进行下一步操作。参数可选。如果 multipart 属性为 true 则这个必须为 true,否则将引发异常。注意,主线程上的同步请求很容易破坏用户体验,应避免;实际上,许多浏览器以完全启用主线程上的同步XMLHttpRequest支持。在Worker中允许同步请求。
  • username:字符串,表示用户名用于认证用途,默认为null。参数可选。
  • password:字符串,表示密码用于认证用途,默认为null。参数可选。

因此,前两个参数是必须要添加的。请求初始化后,就可以调用send() 方法发出 HTTP 请求。如果是异步请求(默认异步请求),则此方法会在请求发送后立即返回;如果是同步请求,则此方法直接响应到达后才会返回。该方法有一个可选参数,作为请求主体,请求方法是GET/HEAD,则请求体设置为null。

send(body): void;

该方法的参数是 XMLHttpRequest 请求中要发送的数据体,可以设置的值为:

  • Document:发送 Document 类型的数据,但发送之前会被序列化。
  • BodyInit:可以是 Blob/BufferSource/FormData/URLSearchParams/ReadableStream<Uint8Array>/string 这几种类型的数据。
  • null。如果没有指定值,默认值就是 null。

因此,创建完XMLHttpRequest对象后,就会按顺序调用open()和send()方法来发送请求。而最常用的方法就是 GET 和 POST 方法。

GET

GET 请求方法,主要用于查询服务器信息。而查询的参数要正确编码并添加到URL后面,例如 example.jsp?username=Alpha&password=a123456,参数之间会用&符号分隔,然后才能传给 open() 方法。该方法最常见的错误就是格式不对,因此可以使用 encodeURIComponent() 函数对字符串进行编码。

let url = "example.jsp";
url = addParam(url, "username", "Alpha");
url = addParam(url, "password", "a123456");

xhr.open('get', url, true);

function addParam(url, name, value) {
    url += (url.indexOf("?") == -1 ? "?" : "&");
    url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
    return url;
}

addParam() 函数保证 XMLHttpRequest 发送请求的 URL 格式正确。

POST

POST 请求方法,主要用于向服务器发送数据。POST 请求会在请求体中携带要提交的数据。POST 请求在传参上不用像 GET 请求那样将参数拼接在 URL 后面,而是使用 send() 方法来携带要提交的数据。

默认情况下,对服务器而言,POST 请求与HTML表单提交是不一样的。服务器逻辑需要读取原始 POST 数据才能取得浏览器发送的数据。不过,还可以使用 XML 模拟表单提交。为此,第一步需要把 Content-Type 头部设置为 “application/x-www-formurlencoded”,这是提交表单时使用的内容类型。第二步是创建对应格式的字符串。POST 数据此时使用与查询字符串相同的格式。如果网页中确实有一个表单需要序列化并通过 XMLHttpRequest 发送到服务器,则可以使用 serialize() 函数来创建相应的字符串,如下所示:

function submitData() {
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                console.log(xhr.responseText);
            } else {
                alert("请求失败: " + xhr.status);
            }
        }
    };
    xhr.open("post", "example.jsp", true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    // ID为 user-info 的表单元素
    let form = document.getElementById("user-info");
    xhr.send(serialize(form));
}

注意:POST 请求相比 GET 请求要占用更多资源。从性能方面说,发送相同数据的数据,GET请求比 POST 请求快两倍。

响应

当服务器收到请求并响应后,XMLHttpRequest 对象会有以下属性被填充数据:

  • status:响应的 HTTP 状态码。
  • stautsText:响应的 HTTP 状态描述。
  • response:响应的正文。
  • responseText:作为响应体返回的文本。
  • responseXML:如果响应的内容类型是 "text/xml"或"application/xml",那就是包含响应数据的 XML DOM 文档。

一般都是通过 status 属性来确保响应是否成功返回。当 status 为 2xx 表示成功,为 304 表示资源未被修改,而是从缓存中取出的。这时的 responseText 或 responseXML 属性中会有内容。因此,我们可以使用 status 属性来判断响应是否有效,如下所示:

xhr.open("get", "example.txt", false);
xhr.send(null);

if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
    console.log(xhr.responseText);
} else {
    console.log("Request was unsuccessful: " + xhr.status);
}

response

XMLHttpRequest.response 属性返回响应的数据体(即 HTTP 响应的 body 部分)。返回的类型为 ArrayBuffer、Blob、Document、Object或DOMString中的一个。具体类型由 XMLHttpRequest.responseType 类型决定。

当请求尚未完成或尚未成功,该值为 null。但当 responseType 属性设置成 "text" 或空字符串("") 且当请求状态在LOADING时,response属性包含到目前为止该请求已经取得的内容。

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
        console.log(xhr.response);
    }
}

responseType

XMLHttpRequest.responseType 属性是一个字符串,返回响应数据的类型。允许手动设置返回数据的类型。如果设置为空字符串,则使用默认的"text"类型。

当 responseType 设置为一个特定的类型时,需确保服务器返回的类型和你所设置的类型是兼容的。如果不兼容,即使服务器返回了数据,数据也会变成null。responseType 属性支持以下几种值:

  1. "":当responseType为空字符串时,与 text 相同,表示服务器返回文本数据。
  2. "arraybuffer":表示服务器返回的是一个包含二进制数据的ArrayBuffer 对象。
  3. “blob”:表示服务器返回的是一个包含二进制数据的 Blob对象。
  4. “document”:表示服务器返回的是一个HTML Document 或 XML Document,这取决于接收数据的 MIME 类型。
  5. “json”:表示将接收到的服务器数据视为JSON来进行解析并得到。
  6. “text”:表示服务器返回的是以DOMString对象表示的文本。

上面几种类型之中,text类型适合大多数情况,而且直接处理文本也比较方便。document类型适合返回HTML/XML文档的情况,这意味着,对于那些打开 CORS 的网站,可以直接用 Ajax 抓取网页,然后不用解析 HTML 字符串,直接对抓取回来的数据进行 DOM 操作。blob 类型适合读取二进制数据,比如图片文件。XMLHttpRequest.responseType属性要在调用 open() 方法之后,并且在调用 send() 方法之前调用。

let xhr = new XMLHttpRequest();
xhr.open("GET", "example.jsp", true);
xhr.responseType = "json";
xhr.send(null);

readyState

XMLHttpRequest.readyState 属性返回一个无符号短整型数字,表示XMLHttpRequest对象的当前状态。该对象会返回以下某个值:

  • 返回 0,未初始化(Uninitialized),状态为 UNSENT。表示代理被创建,但尚未调用 open() 方法。
  • 返回 1,状态为 Open 已打开(Open),状态为OPENED。表示 open() 方法已被调用,但尚未调用 send() 方法。
  • 返回 2,已发送(Sent),状态为HEADERS_RECEIVED。表示已调用 send() 方法,并且头部和状态已经可获得,但尚未收到响应。
  • 返回 3:接收中(Receiving),状态为LOADING。表示已经收到部分响应。
  • 返回 4:已完成(Complete),状态为DONE。表示请求操作已完成。意味着数据传输已经彻底完成或失败。

通信过程中,每当 XMLHttpRequest 对象状态发送变化,readyState 属性值就会被改变,并会触发 onreadystatechange事件。并且XMLHttpRequest对象调用abort()方法,终止请求,也会造成 readyState属性变化。为保证兼容性,onreadystatechange事件应在open()方法之前赋值。如下所示:

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            console.log(xhr.responseText);
        } else {
            alert("Request was unsuccessful: " + xhr.status);
        }
    }
};
xhr.open("get", "example.txt", true);
xhr.send(null);

如果之前使用的是异步请求并想在响应之前取消,可以调用 abort() 方法:

let xhr = new XMLHttpRequest();
xhr.open("get", "example.jsp", true);
setTimeout(function() {
    if (xhr) {
        xhr.abort();
        xhr = null;
    }
}, 5000);	// 5秒后,终止 Ajax 请求

调用这个方法后,XMLHttpRequest 对象会停止触发事件,并阻止访问这个对象上任何与响应相关的属性,而 readyState 属性变为 4,status 属性变为 0 。中断请求后,应该取消对 XMLHttpRequest 对象的引用。由于内存问题,不推荐重用 XMLHttpRequest 对象。

HTTP头部

在 HTTP 的每次请求和响应中都会携带一些头部字段,默认请求下,XMLHttpRequest 请求会发送以下头部字段。

  • Accept:浏览器可以处理的内容类型。
  • Accept-Charset:浏览器可以显示的字符集。
  • Accept-Encoding:浏览器可以处理的压缩编码类型。
  • Accept-Language:浏览器使用的语言。
  • Connection:浏览器与服务器的连接类型。
  • Cookie:页面中设置的 Cookie。
  • Host:发送请求的页面所在的域。
  • Referer:发送请求的页面的 URI。
  • User-Agent:浏览器的用户代理字符串。

XMLHttpRequest对象通过一些方法暴露与请求和响应相关的头部字段。

setRequestHeader()

XMLHttpRequest.setRequestHeader() 方法是设置 HTTP 请求头部字段的方法。此方法接收两个参数:第一个参数是头部属性名,第二个参数是头部属性值。为保证请求头被发送,必须在 open() 之后,send() 之前调用。如果多次调用,设置同一个字段的值会合并成单一的值发送。如下所示:

let xhr = new XMLHttpRequest();
xhr.open("get", "example.jsp", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Custom-Header", "Custom-Value");
xhr.send(null);

自定义头部要区别于浏览器正常发送的头部,否则会影响服务器正常响应。默认头部在有些浏览器上可以重写。而自定义一些 header 属性进行跨域请求时,可能会遇到 “not allowed by Access-Control-Allow-Headers in preflight response”,你可能需要在你的服务端设置 “Access-Control-Allow-Headers”。

getResponseHeader()/getAllResponseHeaders()

XMLHttpRequest.getResponseHeader() 方法用于返回 HTTP 响应头中指定的属性值。如果在返回时,有多个一样的名字,那么返回的值就是用逗号和空格分隔开的字符串。

而 XMLHttpRequest.getAllResponseHeaders() 方法返回所有的响应头,是以 CRLF 分隔(回车+换行)的字符串,如果没收到服务器回应,该属性为 null。以下就是该方法返回的字符串样子:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Content-Length: 0
Content-Type: application/json;charset=UTF-8
Date: Sun, 13 Dec 2020 11:46:23 GMT
Server: Apache-Coyote/1.1

通过解析以上头部字段的输出,就可以知道服务器发送的所有头部,而不需要单独去检查了。

withCredentials

XMLHttpRequest.withCredentials 属性是一个Boolean类型,用来指定跨域请求时,是否应带有用户信息(如Cookie和认证的HTTP头信息)。默认值是 false,即向 sample.com 发送跨域请求时,不会发送 sample.com 设置在本机上的 Cookie。

当需要跨域 AJAX 请求发送 Cookie 时,需要设置 XMLHttpRequest.withCredentials 为 true。同源请求无需设置。而想要这个属性生效,服务器需要显示返回 Access-Control-Allow-Credentials 头信息。

Access-Control-Allow-Credentials: true

注意:脚本总是遵守同源策略,无法从 document.cookie 或者 HTTP 响应的头信息中读取跨域的 Cookie,无论 XMLHttpRequest.withCredentials 的属性值是true或false。

abort()

XMLHttpRequest.abort() 方法用于终止已被发出的请求。当一个请求被终止,readyState 和 status 属性都会被置为 0。

事件

XMLHttpRequest 对象的事件基本上都和请求进度有关,以下列出与 XMLHttpRequest 对象有关的事件:

  • abort:请求中止时(比如用户取消)触发。如果发生错误导致中止,不会触发该事件。
  • error:请求错误时触发。
  • load:请求成功并完成响应时触发,不用检查 readyState 属性,可替代 readystatechange 事件。
  • loadstart:请求成功时并接收到响应的第一个字节时触发。也适用于 <img> 和 <video 元素。
  • loadend:请求成功并响应完成时,且在 error、abort、load 等事件之后触发。
  • progress:在请求接收到数据时候被周期性触发。
  • timeout:请求超时时触发。

触发的先后顺序为 loadstart > progress > error/abort/load > loadend。

let xhr = new XMLHttpRequest();
xhr.onloadstart = function(event) {
    console.log("请求开始:" + event);
};
xhr.addEventListener("progress", function(event) {
    let divStatus = document.getElementById("status");
    divStatus.innerHTML = event.lengthComputable;
    if (event.lengthComputable) {
        divStatus.innerHTML = divStatus.innerHTML + "\n" + "Received " + event.position + " of " +
            event.total +
            " bytes";
    }
}, false);
xhr.onabort = function() {
    console.log("请求中止");
};
xhr.onload = function(event) {
    if ((xhr.status >= 200 && xhr.status < 300) ||
        xhr.status === 304) {
        console.log(xhr.responseText);
    } else {
        console.log("请求失败:" + xhr.status);
    }
};
xhr.onerror = function(event) {
    console.error("请求错误:" + event);
};
xhr.onloadend = function(event) {
    console.log("请求完成:" + event);
};
xhr.ontimeout = function() {
    console.error("请求超时。");
};
xhr.open("get", "http://localhost:8088/servlets/ajaxGet", true);
xhr.timeout = 5000; // 5秒超时
xhr.send(null);
setTimeout(function () {
    if (xhr) {
        xhr.abort();
        xhr = null;
    }
}, 4000);		// 4 秒之后,终止AJAX请求

其中,progress 事件触发会收到 event 对象,该属性包含 lengthComputable、position 和 totalSize 这三个属性:

  • lengthComputable:布尔值属性,表示进度信息是否可用。
  • position:接收的字节数。
  • total:响应的 Content-Length 头部定义的总字节数。

进度事件

进度事件定义了客户端/服务端通信,用于测量如 HTTP 请求(XMLHttpRequest或<img>、<audio>、<video>、<style>、<link>等底层资源的加载)等底层流程进度的事件。继承于 Event。原生提供ProgressEvent()构造函数生成事件对象。如下所示:

ProgressEvent(type, {lengthComputable: boolean, loaded: number, total: number});

构造函数中有两个参数:

  • 第一个参数返回的是字符串,表示事件的类型,这个参数是必须的。
  • 第二个参数是配置对象,表示事件的属性,该参数可选。除了继承 Event 接口的配置属性外,还可以是下面的属性,属性可选。
    • lengthComputable:布尔值,表示加载的总量是否可以计算,默认是 false。
    • loaded:整数,表示已经加载的量,默认是 0。
    • total:整数,表示需要加载的总量,默认是 0。

进度相关的事件都是继承自 ProgressEvent 接口的,该接口用来描述外部资源加载的进度。而浏览器原生提供 ProgressEvent() 构造函数来生成事件实例。如下所示:

let event = new ProgressEvent(type, options);

而构造函数中接收的两个参数:第一个参数是字符串,表示事件的类型,这个参数是必须的;第二个参数是配置对象,表示事件的属性,该参数可选。配置对象除了可以使用 Event 接口的配置属性,还可以使用下面的属性,所有这些属性都是可选的。

  • lengthComputable:布尔值,表示加载的总量是否可以计算,默认是 false。
  • loaded:整数,表示已经加载的量,默认是 0。
  • total:整数,表示需要加载的总量,默认是 0。

属性

ProgressEvent 除了从 Event 继承的属性与方法外,还有三个与构造函数中对应的三个属性。

  • ProgressEvent.lengthComputable:只读属性,是一个 Boolean 标志,指示基础流程是否可以计算总工作量和已经完成的工作量。换句话说,它告诉进度是否可测量。
  • ProgressEvent.loaded:只读属性,表示一个 unsigned long long,代表基础流程已经完成的工作量。可以通过属性和 ProgressEvent.total 来计算完成的工作量。使用 HTTP 下载资源时,这仅代表内容本身的一部分,而不代表头和其它开销。
  • ProgressEvent.total:只读属性,表示一个 unsigned long long,表示基础流程正在执行的工作总量。使用 HTTP 下载资源时,这仅代表内容本身,而不代表头和其它开销。

如果 ProgressEvent.lengthComputable 为 false,ProgressEvent.total 实际上是没有意义的。

XMLHttpRequest Level 2

XMLHttpRequest Level 2 是在 XMLHttpRequest Level 1 的基础上进一步的扩展。但并非所有浏览器都实现了 XMLHttpRequest Level 2 的所有功能,也可能只实现了部分功能。

FormData

在 XMLHttpRequest Level 2 中新增了 FormData 类型,主要用于将数据编译成键值对,使用XMLHttpRequest来发送数据。也用于创建与表单类似格式的数据。创建一个FormData对象,如下所示:

let data = new FormData();
data.append("username", "Clark");
data.append("account", "addie");


let request = new XMLHttpRequest():
request.open("post", "http://example.com/submitform.jsp");
request.send(data);

append() 方法接收两个参数:键,相当于表单字段名;值,相当于表单字段名的值。当然,也可以直接给 FormData 构造函数传入表单元素,也可以将表单中的数据作为键值对填充进去,也可以附加额外的数据到FormData对象中:

let form = document.querySelector("form");
let data = new FormData(form);

data.append("serialnumber", 134);

而使用 FormData之后,可以不再需要给 XMLHttpRequest对象显式地设置任何请求头部。XMLHttpRequest对象能够识别作为 FormData对象传入的数据类型并自动配置相应的头部。

timeout

XMLHttpRequest.timeout 属性是一个表示发送数据后等待的毫秒数的一个整数,响应请求时间超出该属性设置的毫秒数,就会中断该请求。IE8 给 XMLHttpRequest 添加了该属性,并在 XMLHttpRequest Level 2 中添加了该特性。默认值为 0,当超时时,就会触发 timeout 事件。如下所示:

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
            console.log(xhr.responseText);
        } else {
            console.log("请求失败:" + xhr.status);
        }
    }
};
xhr.ontimeout = function() {
    console.log("请求超时。" );
};
xhr.open("get", "http://localhost:8088/servlets/ajaxGet", true);
xhr.timeout = 1000; // 1秒超时
xhr.send(null);

上面的例子演示了设置超时timout属性值,超时后请求中断触发ontimeout事件,并将 status 属性值置 0。但readyState属性值仍为 4,因此也会调用onreadystatechange 事件。

upload

XMLHttpRequest.upload 属性会返回一个 XMLHttpRequestUpload 对象,代表上传进度。这个对象不透明,但作为一个 XMLHttpRequestEventTarget,可以通过对其绑定事件来追踪它的进度。

XMLHttpRequest.upload 属性可以监听 loadstart/progress/abort/error/load/timeout/loadend 这几种事件。

<body>
<progress id="uploadprogress" min="0" max="100" value="0">0</progress> <br>
<input type="file" id="upload_files" /> <br>
<button onclick="upload()">上传</button>
</body>
<script>
    function upload() {
        let resource = document.getElementsByTagName('input')[0].files[0];
        // 此处进行 ajax 上传
        let xhr = new XMLHttpRequest();
        // 预置的 formdata 对象,详情查看 ajax level 2,
        let data = new FormData();
        data.append("resource", resource);
        xhr.open("post", "http://localhost:8088/servlets/upload");
        xhr.onload = function() {
            if (xhr.status === 200) {
                console.log("上传成功");
            } else {
                console.log("上传出错");
            }
        };
        xhr.onerror = function(e) {
            console.error('An error occurred while submitting the form. Maybe your file is too big');
        };
        // 上传进度事件
        xhr.upload.addEventListener('progress', function (ev) {
           if (ev.lengthComputable) {
               let complete = (ev.loaded / ev.total * 100 | 0);
               let progress = document.getElementById('uploadprogress');
               progress.value = complete;
           }
        });
        xhr.send(data);
    }
</script>

当进行上传操作时,如果要跨域上传,需要在服务器设置 CORS。

跨源资源共享(CORS,Cross-Origin Resource Sharing)定义浏览器与服务器如何实现跨源通信。使得 XMLHttpRequest 请求克服了同源使用的限制。简单的授权访问,在服务器设置请求头:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers

overrideMimeType()

XMLHttpRequest.overrideMimeType() 方法用来重写 XMLHttpRequest 响应的 MIME 类型。是 Firefox 首次引入,在 XMLHttpRequest Level 2 中添加了该方法。因为响应返回的 MIME 类型决定了 XMLHttpRequest 对象如何处理响应。例如服务器实际发送的是 XML数据,但响应头中MIME类型设置的是text/plain,浏览器不会自动解析,responseXML属性值是null。此时调用overrideMimeType() 可以保证将响应当成 XML 而不是纯文本来处理:

let xhr = new XMLHttpRequest();
xhr.open("get", "example.jsp", true);
xhr.overrideMimeType("text/xml");
xhr.send(null);

注意:为正确覆盖响应的 MIME 类型,该方法必须在 send() 方法之前调用。

小结

Ajax 是无需刷新当前页面即可从服务器获取数据的一种方法,其中核心对象是 XMLHttpRequest,最早由微软发明,并在 IE5 中引入。之后,其它浏览器都实现了该对象。W3C 虽然也引入了 Web 标准。虽然不同浏览器有些差异,但基本使用是相对较规范的,因此可以放心使用。

关注公众号「海人为记」,回复「资源」即可获得免费资源!
在这里插入图片描述

SAN存储与协议,了解SCSI、FC和ISCSI 在前面我们介绍SAN存储及iSCSI协议的时候了解到SAN存储其实是一个CS架构的系统。存储系统本身就是整个系统的服务端。以IP-SAN(也就是基于iSCSI的SAN存储)为例,其整体架构如图1所示。 图1 CS架构 对于存储系统来说,通常是由专业的存储厂商提供,比较知名的如EMC、NetAPP、IBM和日立等等。国内存储厂商也迅速崛起,比较知名的如华为、宏杉、浪潮和同友等等。另外,还有一些小的存储厂商,他们往往集中在某个领域,比如专注文件系统或者块存储等等。 除了专业的存储设备外,其实Linux 阅读详情

相关推荐

QT的温湿度显示系统

大家好,这里是石侃侃的博客,欢迎前来讨论这篇文章介绍的是DHT11在2440上的基于Qt5.6的应用基于单片机系统的温湿度监测系统构成框图如图2-1所示。图2-1 系统构成框图该系统采用单片机s3c2440作为了本设计的核心元件。利用LCD作为了显示器件,利用触摸屏作为用户界面输入设备,第一行显示当前实时的温度,湿度,第二行依次显示历史时刻最高的温度值,最高的湿度值。第三行是一个文本框,记录了程...

zxpcus的博客 1万+

worker里的ajax,Web Worker 调用Ajax

Web Worker -- Ajax通常来讲,Ajax 和 Web Worker 都是异步执行的,彷佛没有必要在Web Worker里调用Ajax,若是存在这种状况,Ajax 须要按照一个队列里数据排列的顺序同步发送请求,若是不想页面被阻塞,这种状况下能够使用Web Worker 而且须要在Web Worker里使用Ajax。或者说非要在Web Woker里使用Ajax。javascript在We...

weixin_29798439的博客 1223

ZLMediaKit源码分析(二)推流创建

ZLMediaKit推流结构体创建是在RtspSession::onRecv()之后。如何触发onRecv()请参考上一篇文章这里不在赘述。

cliffordl的专栏 5072

js使用webWorker实现多线程

js使用webWorker实现多线程 原生js使用worker index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=dev

总柴的博客 2033

MinerU安装指南:从源码到验证的完整流程

本文详细介绍了MinerU文档转换工具的安装流程,从源码获取、依赖安装到验证步骤,提供了完整的安装指南和常见问题解决方案。特别适合技术写作者和开发者快速部署这款高效的文档转换工具,提升工作效率。

weixin_29243279的博客 544

Spring Boot整合AWS S3文件上传实战:从配置到权限管理全流程解析

本文详细解析了Spring Boot整合AWS S3文件上传的全流程,包括基础配置、核心上传功能实现、高级权限控制及安全最佳实践。通过实战案例展示如何高效处理文件上传、大文件分片及权限管理,帮助开发者构建健壮的文件管理系统。特别强调AWS S3的高可用性和安全性,适用于企业级应用开发。

sam99的博客 283

worker里的ajax,关于Web Worker你必须知道的7件事

### 介绍通过使用Web Worker, 我们可以在浏览器后台运行JavaScript, 而不占用浏览器自身线程。Web Worker可以提高应用的总体性能,并且提升用户体验。如果你想在自己的Web应用中使用Web Worker, 不妨来了解一下有关Web Worker的7件事。#### 1. Web Worker 可以让你在后台运行Javascript一般来说Javascript和页面的UI会...

weixin_35683614的博客 571

保姆级教程:用Docker Compose一键部署WVP-PRO+ZLM+录像服务(含Nginx反代)

本文提供了一套完整的容器化GB28181视频平台部署方案,通过Docker Compose实现WVP-PRO、ZLMediaKit(ZLM)和录像服务的一键式部署。详细介绍了环境准备、架构设计、容器化部署实战以及高级配置优化,帮助用户快速搭建高性能视频监控管理平台,适用于安防行业和物联网设备管理场景。

weixin_30415113的博客 861

webworker和ajax的区别

虽然AJAX操作是异步的,但它主要关注于客户端与服务器之间的数据交换,而不是多线程之间的通信。AJAX:在主线程中运行,但它是异步的,允许在不刷新整个页面的情况下与服务器交换数据并更新页面内容。AJAX:主要用于实现前后端的数据交互,无需刷新整个页面即可更新页面内容,如动态加载数据、表单验证和提交、实时搜索等。Web Worker:由于运行在独立的线程中,不能直接访问DOM(文档对象模型),也不能执行与界面相关的操作。AJAX:可以访问和操作DOM,因为它在主线程中运行,可以直接更新页面内容。

2201_75673611的博客 370

RK3588 Android12 添加HDMI和喇叭声音通道切换选项

rk3588 android12系统默认接hdmi out时,声音会切换到hdmi out输出,主板声卡喇叭输出会没有声音输出。现在添加一个选项设置hdmi out时,声音可以保持主板声卡喇叭输出。

Android系统开发笔记 4163

【红外DDE算法】一种应用于高动态范围红外可视化的算法

【红外DDE算法】一种应用于高动态范围红外可视化的算法 - 这个算法背后的动机 - 展示这个算法的流程 - 然后讨论各个可调参数的意义。

sunwindl91181的博客 1682

worker里的ajax,service-worker

我有一个带有HTML,CSS和JS基本'shell'的应用程序。页面的主要内容是通过多个ajax调用加载到API,该API位于我的应用程序运行的另一个URL上。我已经设置了一个服务工作者来缓存应用程序的主要“shell”:var urlsToCache = ['/','styles/main.css','scripts/app.js','scripts/apiService.js','third_...

weixin_34886207的博客 443

virtuoso:layout如何做flat修drc

有些drc在virtuoso layout中修更节省时间,比如遇到一些via array需要做删改时,发现工具把via array做成了一个cell,如图。去改cell可能会影响很多via,所以最好的办法是做flat,去调整cut,比如删除。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 342

ajax传formdata类型的数据_快速了解JavaScript的Ajax

概述Ajax(Asynchronous JavaScript and XML,即异步 JavaScript 和 XML)技术用于与服务器交换数据并刷新部分页面,实现更好的用户体验。Ajax 的核心对象是 XMLHttpRequest,通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。由微软实现并在 IE5 中支持,用于执行异步网络请求。虽然 Ajax...

weixin_39523835的博客 278

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

$.ajax接收url传参_快速了解JavaScript的Ajax

概述Ajax(Asynchronous JavaScript and XML,即异步 JavaScript 和 XML)技术用于与服务器交换数据并刷新部分页面,实现更好的用户体验。Ajax 的核心对象是 XMLHttpRequest,通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。由微软实现并在 IE5 中支持,用于执行异步网络请求。虽然 Ajax 是 As...

weixin_36358383的博客 283

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

prototype.js开发笔记

覆盖版本 1.3.11. Prototype是什么?或许你还没有用过它, prototype.js 是一个由Sam Stephenson写的JavaScript包。这个构思奇妙编写良好的一段兼容标准的一段代码将承担创造胖客户端, 高交互性WEB应用程序的重担。轻松加入Web 2.0特性。如果你最近体验了这个程序包,你很可能会发现文档并不是它的强项之一。像

589

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

AJAX请求

用于局部刷新数据,(不刷新页面的情况下,提交数据)AJAX使用分为4个步骤1. 创建 创建对象 new XMLHttpRequest();2. 配置 xhr.open(请求方式,请求地址,是否异步); 请求方式:get、post 是否异步:true-异步、false-同步 异步:多个任务按顺序开始,不一定按顺序结束。eg:下载任务、图片加载 同步:上一个任务结束,下一个任务开始。eg:弹窗alert3. 响应

qq_57215961的博客 132

.ajax语法beforesend(xhr)修改跨域请求头_快速了解JavaScript的跨域

浏览器有一个重要的安全策略,就是 同源策略,它用于限制不同源之间资源的交互。能够帮助阻挡一些恶意的访问,减少可能被攻击的媒介。下面看一下与该 URL http://chat.example.com/u1/arts1/101011.html 的源进行对比的示例。URL结果原因http://chat.example.com/u2/arts1/101012.html同源路径不同http://c...

weixin_29969209的博客 382

JS知识全汇总精选(快速复习就靠它了,建议收藏!!)

js gitee

m0_58620483的博客 1228

jquery,js,jsp,ajax,EL表达式的区分

简单点说:jQuery是轻量级的js框架,封装了很多js方法,简单易用;js就是对页面的渲染,来实现一些逻辑,现在应该很少用原始js了吧;JSP就是页面的展示;ajax最多用途是做前后台数据交互;json你就把它简单理解成一个特殊的字符串就行了;EL表达式以前用的比较多,就是把后台返回数据在页面展示的一种方法; js:javascript,用于网页前端开发的,在浏览器上运行,文件类型 js

hacker_Lees的博客 3753

python教程视频ajax_Ajax教程

AJAX代表异步JavaScript和XML。 AJAX是一种借助XML,HTML,CSS和Java Script创建更好,更快,更交互的Web应用程序的新技术。AJAX教程涵盖了适用于初学者和专业人士的AJAX技术的概念和示例。AJAX是Asynchronous JavaScript和XML的首字母缩写。 它是一组相互关联的技术,如JavaScript,DOM,XML,HTML/XHTML,CS...

weixin_39580042的博客 140

【AJAX】

这里写目录标题AJAXAJAX简介:AJAX 工作原理AJAX是基于现有的Internet标准 AJAX AJAX简介: AJAX = 异步 JavaScript 和 XML。 AJAX 是一种用于创建快速动态网页的技术。 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。 传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。 有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。

weixin_62336297的博客 110

ajax用来做什么的,jQuery是什么?jQuery能用来做什么?

jQuery是什么?jQuery的字面意思其实就是JavaScript和查询(Query),即用于辅助开发JavaScript的库。jQuery是继prototype之后的又一个优质的Javascript库,属于开源编程语言。jQuery​是一个​快速,小巧,功能丰富​的​JavaScript库​。​jQuery​ 使HTML文档遍历和操作,事件处理和动画等​操作​变得更加​简单​。jQuery的...

weixin_33622128的博客 371

经典的JavaScript入门书

经典的JavaScript入门书 ——《JavaScript基础教程(第7版)》  原版销售累计超过150 000册! 欢迎你使用JavaScript!使用这种容易上手的程序设计语言,可以给网页增色,使网页更好用。本书是一本轻松的JavaScript入门教程,所以即使不是计算机高手,你也可以由此很快学会脚本编写。 本书相关信息:http://www.cnblogs.com/tu...

weixin_34166847的博客 198

想要熟练定位Bug?前后端交互不好好了解一下怎么行?

作为一个合格的软件测试人员, 能够熟练定位bug的位置是属于前端还是后端,是必备技能之一。所以就需要明白前后端数据是怎么进行交互的。   一、网站数据处理主要分为三层   第一层,表示层,这部分可以用HTML代码,CSS/Javascript代码来实现等。通过前端代码可以实现网页的布局和设计。这层又可以称为显示层。也就是你用浏览器打开能看到的网页。   第二层,是业务层,这层是负责处理数据的。常用的代码语言有PHP,JSP,Java等。通过这些后台处理语言的算法来处理前台传回的数据。必要的时候进行操作数据库

dpl12的博客 434

jQuery与JavaScript与ajax三者的区别与联系

简单总结:1、JS是一门前端语言。2、Ajax是一门技术,它提供了异步更新的机制,使用客户端与服务器间交换数据而非整个页面文档,实现页面的局部更新。3、jQuery是一个框架,它对JS进行了封装,使其更方便使用。jQuery使得JS与Ajax的使用更方便 关系比喻:若把js比作木头,那么jquery就是木板(半成品)jQuery与ajax都是js的一个框架,各有各的功能,若js是父亲的话,jque...

qq_37211608的博客 1万+
上一篇: 快速了解JavaScript基础知识
下一篇: JavaScript高级程序设计(第4版)知识点总结
hireny
博客等级 码龄12年 1粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值