Jsonp(跨域方法)

Jsonp

1. 什么是JSONP

image-20230521165909473

2. JSONP的实现原理

image-20230521165917892

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>

<body>
<script>
function success(data) {
console.log('拿到了Data数据:')
console.log(data)
}
</script>

<script src="/lib/getData.js?callback=success"></script>
<!-- <script>
success({ name: 'zs', age: 20 })
</script> -->
</body>

</html>

3. 实现一个简单的JSONP

image-20230521170008214

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>

<body>
<script>
function abc(data) {
console.log('JSONP响应回来的数据是:')
console.log(data)
}
</script>

<!-- <script src="http://ajax.frontend.itheima.net:3006/api/jsonp?callback=abc&name=ls&age=30"></script> -->
<script src="http://jsfiddle.net/echo/jsonp?callback=abc&textrwe=some&pawerr1=text"></script>
</body>

</html>

image-20230521170038937

4. JSONP的缺点

image-20230521170050187

5. jQuery中的JSONP

image-20230521170058881

6. 自定义参数及回调函数名称

image-20230521170105992

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="/lib/jquery-3.6.0.js"></script>
</head>

<body>
<script>
// jQuery 提供的 $.ajax() 函数,除了可以发起真正的 Ajax 数据请求之外,还能够发起 JSONP 数据请求,
$(function () {
// 发起JSONP的请求
$.ajax({
type: 'GET',
url: 'http://jsfiddle.net/echo/jsonp?callback=abc&textrwe=some312&pawerr1=text123',
// 代表我们要发起JSONP的数据请求
// 如果要使用 $.ajax() 发起 JSONP 请求,必须指定 datatype 为 jsonp
dataType: 'jsonp',
// 在使用 jQuery 发起 JSONP 请求时,如果想要自定义 JSONP 的参数以及回调函数名称,可以通过如下两个参数来指定:
jsonp: 'callback',
jsonpCallback: 'abc',
success: function (res) {
document.write(JSON.stringify(res));
console.log(res)
}
})
})
// 默认情况下,使用 jQuery 发起 JSONP 请求,
// 会自动携带一个 callback=jQueryxxx 的参数,jQueryxxx 是随机生成的一个
// 回调函数名称
</script>
</body>

</html>

7. jQuery中JSONP的实现过程

image-20230521170148028

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="/lib/jquery-3.6.0.js"></script>
</head>

<body>
<button id="btnJSONP">发起JSONP数据请求</button>

<script>
// jQuery中JSONP的实现过程
// jQuery 中的 JSONP,也是通过 <script> 标签的 src 属性实现跨域数据访问的,只不过,jQuery 采用的是动态创建和
// 移除 <script> 标签的方式,来发起 JSONP 数据请求。
// 在发起 JSONP 请求的时候,动态向 <header> 中 append 一个 <script> 标签;
// 在 JSONP 请求成功以后,动态从 <header> 中移除刚才 append 进去的 <script> 标签
$(function () {
$('#btnJSONP').on('click', function () {
$.ajax({
url: 'http://jsfiddle.net/echo/jsonp?address=北京&location=顺义',
dataType: 'jsonp',
jsonpCallback: 'abc',
success: function (res) {
document.write(JSON.stringify(res));
console.log(res)
}
})
})
})
</script>
</body>

</html>

8. 案例-淘宝搜索

8.1 要实现的UI效果

image-20230521170217519

8.2 获取用户输入的搜索关键词

image-20230521170224315

8.3 封装getSuggestList函数

image-20230521170230657

8.4 渲染建议列表的UI结构

8.41 定义搜索建议列表

image-20230521170239188

8.42 定义模板结构

image-20230521170245290

8.43 定义渲染模板结构的函数

image-20230521170251792

8.44 搜索关键词为空时隐藏搜索建议列表

image-20230521170258574

8.5 完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入页面的基本样式 -->
<link rel="stylesheet" href="./css/search.css" />
<!-- 导入模板引擎 -->
<script src="./lib/template-web.js"></script>
<!-- 导入 jQuery -->
<script src="./lib/jquery.js"></script>
</head>

<body>
<div class="container">
<!-- Logo -->
<img src="./images/taobao_logo.png" alt="" class="logo" />

<div class="box">
<!-- tab 栏 -->
<div class="tabs">
<div class="tab-active">宝贝</div>
<div>店铺</div>
</div>
<!-- 搜索区域(搜索框和搜索按钮) -->
<div class="search-box">
<input type="text" id="ipt" class="ipt" placeholder="请输入要搜索的内容" />
<button class="btnSearch">
搜索
</button>
</div>
<!-- 搜索建议列表 -->
<div id="suggest-list"></div>
</div>
</div>

<!-- 定义模板引擎 -->
<script type="text/html" id="suggest-items">
{{each result}}
<div id="suggest-item">{{$value[0]}}</div>
{{/each}}
</script>

<script>
$(function () {
// 4.防抖策略(debounce)是当事件被触发后,延迟 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。
// 用户在输入框中连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求,这样可以有效减
// 少请求次数,节约请求资源
// 实现输入框的防抖
var timer = null // 1. 防抖动的 timer
function debounceSearch(keywords) { // 2. 定义防抖的函数
timer = setTimeout(function () {
// 发起 JSONP 请求
getSuggestList(keywords)
}, 500)
}

// 5.缓存搜索的建议列表
// 定义全局缓存对象
var cacheObj = {}


// 1.为了获取到用户每次按下键盘输入的内容,需要监听输入框的 keyup 事件
$('#ipt').on('keyup', function () {
// 1.1清除防抖
clearTimeout(timer)

// 1.2获取文本框文本
const txt = $(this).val().trim()

// 1.5优先从缓存中获取搜索建议
if (cacheObj[txt]) {
return renderSuggestList(cacheObj[txt])
}

// 1.3如果关键词为空,则清空后隐藏搜索建议列表
if (txt.length <= 0) {
return $('#suggest-list').empty().hide()
}

// getSuggestList(txt)
// 1.4防抖渲染数据
debounceSearch(txt)
})

// 2.将获取搜索建议列表的代码,封装到 getSuggestList 函数中
function getSuggestList(goods) {
$.ajax({
type: 'GET',
url: 'https://suggest.taobao.com/sug?q=' + goods,
// 如果要使用 $.ajax() 发起 JSONP 请求,必须指定 datatype 为 jsonp
dataType: 'jsonp',
// 发送到服务端的参数名称,默认值为 callback
jsonp: 'callback',
// 自定义的回调函数名称,默认值为 jQueryxxx 格式
// jsonpCallback: 'abc',
success: function (res) {
renderSuggestList(res)
}
})
}

// 3.渲染建议列表
function renderSuggestList(res) {
// 如果没有需要渲染的数据,则直接 return
if (res.result.length <= 0) {
return $('#suggest-list').empty().hide()
}
// 渲染模板结构
const htmlStr = template('suggest-items', res)
$('#suggest-list').html(htmlStr).show()
// 将搜索的结果,添加到缓存对象中
var k = $('#ipt').val().trim()
cacheObj[k] = res
}

})
</script>
</body>

</html>