一、使用JSONP的原因
由于浏览器安全限制,不同的根域名、二级域名、不同端口之间的数据不可以直接跨域,所以用JSONP(JSON with Padding),其是JSON的一种补充使用方式,不是官方协议,而是利用 Script 标签请求资源可以跨域的特点来解决跨域问题,是一种变通的解决方案。
二、JSONP的缺点
1.只支持GET方法请求。
2.它没有关于JSONP调用的错误处理,一旦回调函数调用失败,浏览器会以静默失败的方式处理。
3.安全性。在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。
三、百度搜索案例实现
百度搜索API接口:
https://suggestion.baidu.com/su?cb=callback&wd=%E7%99%BD%E7%BE%8A
1.简单做个布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
font-size: 16px;
}
ul{
margin-top: 10px;
}
li{
list-style: none;
margin-top: 5px;
text-indent: 5px;
}
.container{
width: 600px;
margin: 20px auto;
}
input{
width: 600px;
}
.options{
width: 600px;
padding: 5px 0;
background-color: #ccc;
}
.options li:hover{
background-color: skyblue;
color: aliceblue;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<input type="text" placeholder="请输入关键词">
<ul class="options">
<li>vue的优缺点</li>
</ul>
</div>
</div>
</body>
</html>
页面效果如下:
2.引入vue(可以下载vue文件,或者使用http的vue)
<script src="./vue.js"></script>
3.创建Vue实例,并在页面绑定搜索API数据。
<script>
let vm = new Vue({
el:"#app",
data:{
keywords_list:[]
}
})
</script>
<li v-for="item in keywords_list">{{ item }}</li>
3.在input上用v-model指令来实现表单元素和数据的双向绑定。用watch实现监听输入的关键词keyword发生的改变。
<input type="text" placeholder="请输入关键词" v-model="keyword">
data:{
keyword:"",
keywords_list:[]
},
watch:{
keyword(value){
console.log(value);
}
}
4.请求JSONP,将请求的数据结果给keywords_list。
1)创建script标签
const script = document.createElement('script')
2)将关键词传给搜索API,设置script的src属性,并将script标签添加到页面中
keyword(value){
// 创建script标签
const script = document.createElement('script')
if(this.keyword !==""){
var url = "https://suggestion.baidu.com/su?cb=callback&wd="+this.keyword
//设置script的src属性
script.src=url;
}
// 将script标签添加到页面中
document.body.appendChild(script)
}
3)将请求的数据结果给页面
function callback(res) {
vm.keywords_list=res.s
}
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
<style>
* {
margin: 0;
padding: 0;
font-size: 16px;
}
ul {
margin-top: 10px;
}
li {
list-style: none;
margin-top: 5px;
text-indent: 5px;
}
.container {
width: 600px;
margin: 20px auto;
}
input {
width: 600px;
}
.options {
width: 600px;
padding: 5px 0;
background-color: #ccc;
}
.options li:hover {
background-color: skyblue;
color: aliceblue;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<input type="text" placeholder="请输入关键词" v-model="keyword">
<ul class="options">
<li v-for="item in keywords_list">{{ item }}</li>
</ul>
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
keyword: "",
keywords_list: []
},
watch: {
keyword(value) {
// 创建script标签
const script = document.createElement('script')
if (this.keyword !== "") {
var url = "https://suggestion.baidu.com/su?cb=callback&wd=" + this.keyword
script.src = url; //设置script的src属性
}
// 将script标签添加到页面中
document.body.appendChild(script)
}
}
})
function callback(res) {
vm.keywords_list=res.s
}
</script>
</body>
</html>