快速了解JavaScript的Ajax

SAR成像概述 1. 发展概述 雷达是英文Radar(Radio detection and ranging)的音译,原意为“无线电探测与测距”。雷达的发明是无线电发展史上的里程碑,二战时,英国急需通过雷达探测空中金属物体来帮助搜寻德国飞机,这期间,雷达技术飞速发展,发展出了地对空、空对地轰炸、空对空火控、敌我识别等功能。雷达在第二次世界大战中发挥了重大作用,至今仍是军用和许多民用领域的重要传感器。 早期雷达系统通过时间延迟来测距,通过天线指向来测角,通过多普勒频移测速。1951年,Carl Wiley发现,通.. 阅读详情

概述

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 标准。虽然不同浏览器有些差异,但基本使用是相对较规范的,因此可以放心使用。

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

YOLOv8 | 代码逐行解析(二) | 从yaml文件到模型定义(代码逐行注释,小白必看) 本文给大家带来的是YOLOv8项目的解读,之前给大家分析了YOLOv8的项目文件分析,这一篇文章给大家带来的是模型训练从我们的yaml文件定义到模型的定义部分的讲解,我们一般只知道如何去训练模型,和配置yaml文件,但是对于yaml文件是如何输入到模型里,模型如何将yaml文件解析出来的确是不知道的,本文的内容接上一篇的代码逐行解析(一) 项目目录分析,本文对于小白来说非常友好,非常推荐大家进行阅读,深度的了解模型的工作原理已经流程,下面我们从yaml文件来讲解。 阅读详情

相关推荐

软考中级信息系统监理师(第二版)-第21章基础设施工程监理

由于网络信息技术的飞速发展,变化日新月异,网络设计不但要保证目前网络传输容量的要求,也要考虑今后网络的发展,满足当前以及今后相当一段时间内的网络需求,便于向新技术的升级和衔接,同时又需要保护原有的投资。通用布缆系统工程中,承建单位的竣工文档主要包括以下内容:承建合同,招标文件,投标文件,设计方案,工程实施组织设计方案,工程施工报告,隐蔽工程记录,变更记录,自测报告,信息点分布图(表),园区、楼宇、水平配线表,楼层平面图及无线设备点位图,无线设备信息表,竣工图纸等。多排安装时,列间距不应小于1200mm。

2301_78583973的博客 1400

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

Cadence17.4 Allegro PCB制板(gerber / 光绘)文件输出的顺序及注意点

Cadence Allegro PCB制板文件输出 (gerber 光绘文件输出)

weixin_45331044的博客 1万+

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

Python之ae-toolbox包语法、参数和实际应用案例

ae-toolbox(全称 after-effects-toolbox)是 Python 生态中专门用于 Adobe After Effects(AE)自动化操作 的工具包,基于 AE 的 ExtendScript(JSX)桥接技术,实现 Python 与 AE 的跨语言通信。

王国平的博客 1174

会计-合并-5- 增资、处置交易在合报与个报会计处理

摘要:本文系统梳理了股权投资会计处理的四种情形:从交易性金融资产转为权益法或成本法、权益法转成本法、权益法增持。核心原则是区分个报与合报处理,重点关注原投资公允/账面价值的计量差异及损益确认逻辑。对不丧失控制权的股权处置,个报确认投资收益,合报调整资本公积;丧失控制权时,个报需追溯调整权益法核算,合报计算综合投资收益。一揽子交易的特殊处理强调将过渡性差额暂记其他综合收益,最终丧失控制权时转入当期损益。文末通过典型案例演示了不同情境下的具体计算方法。

qq_34047402的博客 466

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

工业级4~20mA转0~3V信号调理电路原理图设计,已量产(电流传感器)

在工业现场,4~20mA 电流信号是模拟量传输的 “老熟人”—— 抗干扰强、能跑长距离,但嵌入式 MCU 的 ADC 一般只认电压信号。最近做项目时,我设计了一款能覆盖 0~25mA(含超量程冗余)、线性输出 0~3V 的调理电路,经过现场调试挺稳定,分享下细节。

不脱发的程序猿 526

webworker和ajax的区别

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

2201_75673611的博客 370

〖Python接口自动化测试实战篇④〗- 接口自动化测试详解

[接口测试] 是相对来说和我们的功能测试 [最为接近的一种自动化测试手段] ,所以我们首先来学习接口测试的内容。 实现接口的开发与接口的测试,在我们的思维上、想法上、面向的态度上都是不一样的。所以大家要有一个思维上的转换,要认识了解一下 接口测试到底是做什么的、它的功能、意义在哪里。...

易编橙 · 终身成长社群,相遇已是上上签! 5万+

Claude Code(1):手把手教你安装配置 Claude Code

Claude Code 是一款强大的 AI 编程助手工具,能够帮助开发者提升编码效率。本文将详细介绍如何在不同操作系统上安装和配置 Claude Code,让你快速上手这款工具。

blues_C的博客 752

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

姿态传感器/陀螺仪之ICM-42670-P应用原理图设计

ICM-42670-P采用LGA-14封装,尺寸为2.5x3x0.76毫米,工作电压范围为1.71V至3.6V,支持I3CSM、I2C和SPI串行通信接口。其设计目标是提供高精度、低功耗和小型化的解决方案,以满足消费类和工业应用的需求。ICM-42670-P是一款由TDK InvenSense推出的高性能六轴MEMS运动追踪传感器,集成了3轴陀螺仪和3轴加速度计,适用于多种应用场景,包括可穿戴设备、游戏控制器、无人机、AR/VR设备等。

corlin6688的博客 1205

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

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

weixin_39523835的博客 278

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

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

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

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

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

weixin_36358383的博客 283

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

prototype.js开发笔记

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

589

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

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、付费专栏及课程。

余额充值