更新日期:2022/07/22
只要我们一起大笑,可怕的东西就会跑光光了。
友情链接 【Http 通信】CORS 跨域资源共享
jQuery Ajax
jQuery 库支持完整的 Ajax 操作。这里所包含的所有函数和方法用于从服务端加载数据,并且不会导致页面刷新。
快速开始
jQuery 发送的所有 Ajax 请求,内部都会通过调用 $.ajax()
函数来实现。通常没有必要直接调用这个函数,我们可以使用几个已经封装好的简便方法,如: $.get()
和 .load()
。
如果需要用到一些不常见的选项,那么使用 $.ajax()
更灵活。
- 首先准备一个 json 数据,随便写上点什么。
{
"date": "2020-07-14",
"author": "ouseki",
"content": "test-ajax"
}
- 使用
$.get()
来请求上面的 json 数据,并显示在页面上。
快捷方法
这些方法帮你用最少的代码发送常见的 Ajax 请求。
jQuery.get( url [, data ] [, success(data, textStatus, jqXHR) ] [, dataType ] ) // 使用一个 HTTP GET 请求从服务器加载数据。
jQuery.post( url [, data ] [, success(data, textStatus, jqXHR) ] [, dataType ] ) // 使用一个 HTTP POST 请求从服务器加载数据。
jQuery.getJSON( url [, data ] [, success(data, textStatus, jqXHR) ] ) // 使用一个 HTTP GET 请求从服务器加载 JSON 编码的数据。
jQuery.getScript( url [, success(script, textStatus, jqXHR) ] ) // 使用一个 HTTP GET 请求从服务器加载并执行一个 JavaScript 文件。
$("selector").load( url [, data ] [, complete(responseText, textStatus, XMLHttpRequest) ] ) // 从服务器载入数据并且将返回的 HTML 代码并插入至匹配的元素中。
- jQuery.getScript() 示例
使用一个 HTTP GET 请求从服务器加载并执行一个 JavaScript 文件。
// testJavaScript.js
$(function () {
$("#content")
.css("backgroundColor","red")
.text("加载完毕。")
})
- $(“selector”).load() 示例
从服务器载入数据并且将返回的 HTML 代码并插入至匹配的元素中。
<!-- testHtml.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>IT God Road</title>
</head>
<body>
<h3>IT God Road</h3>
<hr>
<P>このあらん限り背後には人間性の歪みがあるのか、道徳の喪失があるのか?</P>
</body>
</html>
全局 Ajax 事件处理器
这些方法用于注册事件处理器,用来处理页面上的任何 Ajax 请求,当某些事件触发后,这些事件处理器被调用。
如果 jQuery.ajaxSetup() 中的 global 属性被设置为 true (默认设置),那么每个 Ajax 请求都会触发全局事件。
注意:全局事件绝对不会被跨域(cross-domain)脚本或 JSONP 请求触发,和 global 属性的设置毫无关系。
$(document).ajaxComplete( handler(event, XMLHttpRequest, ajaxOptions) ) // 当 Ajax 请求完成时(无论成功或失败)执行的回调函数。从 jQuery 1.8 开始 ajaxComplete() 方法只能绑定到 document 元素。
$(document).ajaxSuccess( handler(event, XMLHttpRequest, ajaxOptions) ) // Ajax 请求成功时执行的回调处理函数。
$(document).ajaxError( handler(event, jqXHR, ajaxSettings, thrownError) ) // Ajax 请求出错时执行的回调处理函数。
$(document).ajaxSend( handler(event, jqXHR, ajaxOptions) ) // Ajax 请求发送之前绑定一个要执行的函数。
$(document).ajaxStart( handler() ) // 在 Ajax 请求刚开始时执行一个处理函数。
$(document).ajaxStop( handler() ) // 在 Ajax 请求完成时执行一个处理函数。
- jQueryTest.js
$(function () {
$(document).ajaxComplete(function () {
$("ol").append("<li>Triggered ajaxComplete handler.</li>");
});
$(document).ajaxSuccess(function () {
$("ol").append("<li>Triggered ajaxSuccess handler.</li>");
});
$(document).ajaxError(function () {
$("ol").append("<li>Triggered ajaxError handler.</li>");
});
$(document).ajaxSend(function () {
$("ol").append("<li>Triggered ajaxSend handler.</li>");
});
$(document).ajaxStart(function () {
$("ol").append("<li>Triggered ajaxStart handler.</li>");
});
$(document).ajaxStop(function () {
$("ol").append("<li>Triggered ajaxStop handler.");
});
})
辅助函数
这些函数用于辅助完成 Ajax 任务。
jQuery.param( obj [, traditional] ) // 创建一个数组或对象序列化的的字符串,适用于一个 URL 地址查询字符串或 Ajax 请求
$("selector").serialize() // 将用作提交的表单元素的值编译成字符串。
$("selector").serializeArray() // 将用作提交的表单元素的值编译成拥有 name 和 value 对象组成的数组。
底层接口
这些函数可以用于发起任意 Ajax 请求。
jQuery.ajax( [ url , settings ] ) // 执行一个异步 HTTP Ajax 的请求。
jQuery.ajaxPrefilter( [dataTypes ], handler(options, originalOptions, jqXHR) ) // 在每个请求之前被发送和 $.ajax() 处理它们前处理,设置自定义 Ajax 选项或修改现有选项。
jQuery.ajaxSetup( options ) // 为以后要用到的 Ajax 请求设置默认的值。
jQuery.ajaxTransport( dataType, handler(options, originalOptions, jqXHR) ) // 创建一个对象,用于处理 Ajax 数据的实际传输。
- Ajax 请求设置
一个以{键:值}
组成的 Ajax 请求设置,所有选项都是可选的。可以使用$.ajaxSetup()
设置任何默认参数。
jqXHR.success(),jqXHR.error() 和 jqXHR.complete() 回调从 jQuery 1.8开始被弃用,请使用 jqXHR.done(),jqXHR.fail() 和 jqXHR.always() 代替。
属性 | 描述 |
---|---|
accepts | 内容类型发送请求头(Content-Type),用于通知服务器该请求需要接收何种类型的返回结果 |
async | 布尔值,表示请求是否异步处理(跨域请求和 dataType: “jsonp” 请求不支持同步操作)。默认是 true |
beforeSend( jqXHR jqXHR, PlainObject settings ) | 发送请求前运行的函数,此功能用来设置自定义 HTTP 头信息,等等 |
cache | 布尔值,表示浏览器是否缓存被请求页面。默认是 true(dataType 为 “script” 和 “jsonp” 时默认为 false) |
complete( jqXHR jqXHR, String textStatus ) | 请求完成后运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后) |
contents | 一个以 “{字符串/正则表达式}” 配对的对象,根据给定的内容类型,解析请求的返回结果 |
contentType | 发送数据到服务器时所使用的内容和编码类型。默认是:“application/x-www-form-urlencoded; charset=UTF-8” |
context | 为所有 AJAX 相关的回调函数规定 “this” 值 |
converters | 一个数据类型到数据类型转换器的对象。每个转换器的值是一个函数,返回经转换后的请求结果。 (默认: {“* text”: window.String, “text html”: true, “text json”: jQuery.parseJSON, “text xml”: jQuery.parseXML}) |
crossDomain | 如果你想在同一域中强制跨域请求,如JSONP形式,那么需要将 crossDomain 设置为 true (默认: 同域请求为 false, 跨域请求为 true) |
type | 规定请求的类型(GET、POST 等等) |
data | 规定要发送到服务器的数据,将自动转换为请求字符串格式(“{键:值}”)。GET 请求中将附加在 URL 后面 |
dataFilter(Object data, String type) | 用于处理 XMLHttpRequest 原始响应数据的函数。这是一个预过滤功能,净化响应 |
dataType | 预期服务器响应的数据类型,如果不指定 jQuery 将自动根据 HTTP 包 MIME 信息来智能判断。(默认: Intelligent Guess (xml, json, script, or html)) |
error( jqXHR jqXHR, String textStatus, String errorThrown) | 请求失败要运行的函数。错误信息(第二个参数)除了得到 null 之外,还可能是 “timeout”, “error”, “abort” 和 “parsererror” |
global | 布尔值,规定是否为请求触发全局 AJAX 事件处理程序。默认是 true |
headers | 一个额外的 “{键:值}” 对映射到请求一起发送,此设置会在beforeSend 函数调用之前被设置 ;因此,请求头中的设置值,会被beforeSend 函数内的设置覆盖 |
ifModified | 布尔值,规定是否仅在上次请求响应发生改变时才允许请求成功(使用 HTTP 包 Last-Modified 头信息判断)。默认是 false |
isLocal | 布尔值,允许当前环境被认定为“本地”(如文件系统),即使 jQuery 默认情况下不会这么做,默认: 取决于当前的位置协议 |
jsonp | 在一个 jsonp 请求中重写回调函数的名字 |
jsonpCallback | 为 jsonp 请求指定一个回调函数名,这个值将用来取代jQuery自动生成的随机函数名 |
mimeType | 一个 mime 类型用来覆盖 XHR 的 MIME 类型 |
password | 用于响应 HTTP 访问认证请求的密码 |
processData | 布尔值,规定通过请求发送的数据是否转换为查询字符串。默认是 true,如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false |
scriptCharset | 仅适用于当 “script” 传输使用时规定请求的字符集,通常只在本地和远程的内容编码不同时使用 |
statusCode | 一组数值的 HTTP 代码和函数对象,当响应时调用了相应的代码,默认: {} |
success( Object data, String textStatus, jqXHR jqXHR ) | 请求成功后的回调函数 |
timeout | 设置本地的请求超时时间(毫秒)。此设置将覆盖 $.ajaxSetup() 里的全局设置 |
traditional | 布尔值,规定是否使用参数序列化的传统样式 |
type | 请求方式 (“POST” 或 “GET”), 默认为 “GET” |
url | 规定发送请求的 URL,默认是当前页面 |
username | 用于响应 HTTP 访问认证请求的用户名 |
xhr | 用于创建 XMLHttpRequest 对象的函数 |
xhrFields | 一对 “文件名-文件值” 组成的映射,用于设定原生的 XHR 对象 |
- context 示例
this 是在所有的回调中的引用,是这个对象在传递给 $.ajax 的设置中上下文;如果没有指定 context(上下文),this 引用的是 Ajax 设置的本身。
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
$(this).addClass("done");
});
- statusCode 示例
$.ajax({
statusCode: {
404: function() {
alert("page not found");
}
}
});
- jQuery.ajax() 示例
$.ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
JSONP 简介
JSONP JSON with Padding 是 json 的一种使用模式,用于解决主流浏览器的跨域数据访问问题。可以让网页从别的域名(网站)那获取资料,即跨域读取数据。利用
<script>
元素的开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是 JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
为什么我们从不同的域(网站)访问数据需要一个特殊的技术(JSONP)呢?这是因为同源策略。
同源策略 Same origin policy 它是由 Netscape 提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能。所谓同源是指:协议,域名,端口都相同就是同源,否则就是跨域。
现在所有支持 JavaScript 的浏览器都会使用这个策略,可以说 Web 是构建在同源策略基础之上的。浏览器只是针对同源策略的一种实现,是为了保护本地数据不被 JavaScript 代码获取回来的数据污染,因此拦截客户端发出请求后回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。
以百度页面为例,使用浏览器打开控制台:输入 location.origin
即可得到百度的源。
https://www.baidu.com/ 它的协议版本是 https,域名为 www.baidu.com ,端口为 443(https 默认端口号,可省略)。
当知道源以后,就很容易理解同源策略,即只有源相同(域名、协议、端口相同)的客户端脚本才可以读写对方的资源,反之,不同客户端的脚本不能在没有明确授权的情况下读写对方的资源。
- JSONP 的安全隐患
1.任意网站只要通过 jsonp 方式就可以跨域访问目标域名下的信息,解决办法:在跨域请求数据时在参数中加上与目标域名约定好的一个 token 变量,这样其他网站访问该域名时,目的网站通过辨认这个约定好的信息而决定是否可以被跨域访问。
2.不能用 post 方法获取数据,由于基于 src 地址引用方式,在地址中附带参数信息,因此只能用 get 方式获取信息。
3.callback 方法由于是根据用户需求自己实现的,可能会被恶意注入脚本,获取隐私信息。
JSONP 请求过程
众所周知,后端一般给前端返回 json 数据,而使用 Jsonp 的特殊之处就在于前端会传递一个 callback 参数(key)给后端,接着后端返回数据时会将这个 callback 参数的值(value)作为函数名来包裹住 json 数据,最终返给前端的就是一段 js 代码了,这样就巧妙地解决了跨域的问题。
以 JSONP 的方式载入 JSON 数据块。会自动在所请求的 URL 最后添加 ?callback=?
。默认情况下不会通过在 URL 中附加查询字符串变量 “_=[TIMESTAMP]” 进行自动缓存结果,除非将 cache 参数设置为 true。
callback 是回调函数参数,xxx 即是回调函数名称,回调函数名称传到后端后,会被拿来包裹住要返回给前端的 json 数据,最终返回给前端的数据是 xxx(json)
的形式。而前端将会用 script 的方式处理返回数据,来对 json 数据做处理,以此完成一个有效的 Jsonp 请求。此处的 callback 可通过 jsonp 来自定义,xxx 可通过 jsonpCallback 来自定义。
jsonp: 回调函数的参数,是与后端约定好的参数,必须与后端保持一致。不另外定义 jsonp 的话,一般默认为 jsonp:‘callback’。
jsonpCallback: 回调函数名,用来包裹住 json 数据,不另外定义的话,这个参数的值往往是随机生成的。
- 先来用普通的 ajax.get 访问一下非同源的项目。
请求成功,但是响应被 CORS 政策阻止了。
- 再来用 jsonp 访问一下非同源的项目。
使用 Jsonp 跨域,是需要后端配合的。
@RestController
@RequestMapping("/ajax")
public class TestController extends BaseController {
@RequestMapping(value = "/jsonp", method = RequestMethod.GET)
public String jsonp(HttpServletRequest request) throws Exception {
Map<String, String> returnMap = new HashMap<String, String>();
String callback = request.getParameter("callback");
// 获取前端传递过来的数据
String now = request.getParameter("executeTime");
returnMap.put("executeTime", now);
returnMap.put("author", "ouseki");
return callback + "(" + JSONObject.fromObject(returnMap) + ")";
}
}
使用 jsonp 方式的 ajax 前端代码。
ajax: function () {
const url = "http://localhost:8080/ITGodRoad/ajax/jsonp";
const now = new Date();
$.ajax({
url: url,
type: "get",
dataType: "jsonp",
data: { // 数据注意内容必须为字典
executeTime: now // 字典里内容前面 key 可以不加 "",默认会加上 "" 变成字符串但是不会当成变量
}, // 字典后面 value 有 "" 为字符串,没有为变量
jsonp: "callback", // 默认值为 callback ,可省略
jsonpCallback: "jcb", // //用户定义的 callback 回调函数名,用来包裹 json 数据。不另外定义的话,这个参数的值是以 jQuery 开头后面跟一堆随机数生成的。
success: function (json) {
console.log(json);
$("#content").html(json.author + "<br>" + json.executeTime);
},
error: function () {
alert("跨域请求失败。");
}
});
}
前端向后端发送回调函数的函数名(key),后端找到与 key 对应的函数名(value),让该 value 包裹住 json 数据,再返回给前端。
![](https://i-blog.csdnimg.cn/blog_migrate/4f4f96e7331ca6135bd3cb9774496ef1.png)