跨域问题和同源策略
同源策略
是浏览器的一种安全机制,同源即域名、协议、端口完全相同
在同源策略下,只有同源的地址才能相互通过AJAX方式交流
同源指的是两个地址之间的关系,不同源的地址之间的请求称做跨域
http(协议)://www.baidu.com(域名):80(端口-默认80可不写)/index.html
浏览器不允许通过跨域获取数据,但是现代web应用中我们又需要获取不同源地址的资源,必须解决不同源问题,实现跨域请求数据
JSONP
JSON with Padding,借助script标签发送跨域请求的方法
基本原理:
在客户端通过script标签请求服务端的一个地址
script返回的结果带一段全局函数调用的js脚本
这个函数调用会调用我们本地js的一个函数
而函数的实参就是我们想要的数据
jsonp只能发送get请求,jsonp和XHR没有任何关系
JQ中的jsonp
使用$.ajax()方法,只需要把dataType类型设置为jsonp
type="button" value="获取">
// 按钮添加点击事件
$('input').click(function () {
// 以jsonp的方式获取数据
$.ajax({
// 地址:这是一个百度搜索的时候提示文本的接口
url: 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web',
// 方式使用get
type: 'get',
// 设置dataType为jsonp就可以以jsonp方式获取数据
dataType: 'jsonp',
//这里可以设置jsonp的回调函数的名字,如果不设置jq会自动生成一个名字
jsonpCallback: 'abc',
// 这里可以修改回调函数的参数名,默认callback,但如果接口强制要求了参数民,就需要我们手动设置和接口要求的一样
jsonp: 'cd',
// 要传入的数据
data: {
wd: 'ajax'
},
// 打印返回的数据
success: function (data) {
console.log(data)
}
})
})
// 大部分情况下不需要设置回调函数的名字和参数
复制代码
CORS跨域
Cross Origin Resource Share -- 跨域资源共享
无需在客户端做出任何变化,只需要在服务端响应的时候添加一个Access-Control-Allow-Origin的响应头即可,表示这个资源是否支持指定域请求
Access-Control-Allow-Origin的值
为*表示任何源都可以跨域访问这个文件,不安全
值为(一个域名+协议)例如:
http://foo.com
表示只允许指定的源访问
cors跨域现在较常使用
案例:百度搜索
模拟百度搜索时候的自动提示
在百度试一下,打开控制台network,查看文件response看到回调函数名为
jQuery110202399796524493838_1611211395892(参数)
,说明是一个jsonp格式发送的打开headers找到函数名
cb=jQuery110202399796524493838_1611211395892&_=1611211395894
,所以参数名为cd实际接收参数的参数是wd:
&wd=12
(我搜索的就是12)接口地址为
https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web
br /> PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
http-equiv="Content-Type" content="text/html;charset=UTF-8">
楼梯导航效果
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.box {
width: 500px;
margin: 100px auto;
}
.box .l {
float: left;
width: 396px;
border: 2px solid #4e6ef3;
overflow: hidden;
}
.box .l input {
width: 396px;
height: 36px;
border: 0;
outline: none;
}
.box .r {
float: right;
width: 100px;
height: 40px;
border: 0;
background-color: #4e6ef3;
color: #fff;
}
class="box">
class="l">type="text">
class="r" type="button" value="百度一下">
// 获取元素
const $lis = $('.box .l ul li'),
$input = $('.box .l input')
// 给输入框添加键盘抬起事件
$input.keyup(function () {
// 跨域请求
$.ajax({
url: 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web',
// jsonp方式
dataType: 'jsonp',
// 设置参数值为cb
jsonp: 'cb',
// 设置参数
data: {
wd: $(this).val()
},
// 使用返回的数据到ul上
success: function (data) {
if (data.g === undefined) {
return
}
$lis.each(function (i) {
$(this).text(data.g[i].q)
})
}
})
})
复制代码
模版引擎
减少字符串拼接
在模版里面解析json,然后跟html内容进行拼接,性能更好
artTemplate模版引擎(腾讯)
简约、超快的模版引擎
地址:https://github.com/aui/artTemplate
中文文档:https://aui.github.io/art-template/zh-cn/docs/
常用语法:
符号包裹起来的语句则为模版逻辑表达式
为输出表达式
使用
引入模版js文件
创建模版
数据模版绑定
编写解析数据
绑定数据和模版之后得到内容
数据书写到页面上
lang="en">
charset="UTF-8">
name="viewport" content="width=device-width, initial-scale=1.0">
使用模版引擎
class="box">
class="list">
// 创建一个数组
const arr = [{
name: 1
}, {
name: 2
}, {
name: 3
}, {
name: 4
}, {
name: 5
}, {
name: 6
}, ]
//循环遍历数组,把每一个数组中的对象都带入template方法
for (const i of arr) {
// template方法支持两个参数,第一个是要使用的模版的id值,第二个参数是要使用的对象类型的数据,模版可以直接使用对象中的属性名从而获取属性值
// 循环给ul添加li
$('.box .list').append(template('tem', i))
}
复制代码
使用模版引擎改造百度案例
br /> PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
http-equiv="Content-Type" content="text/html;charset=UTF-8">
百度
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.box {
width: 500px;
margin: 100px auto;
}
.box .l {
float: left;
width: 396px;
border: 2px solid #4e6ef3;
overflow: hidden;
}
.box .l input {
width: 396px;
height: 36px;
border: 0;
outline: none;
}
.box .r {
float: right;
width: 100px;
height: 40px;
border: 0;
background-color: #4e6ef3;
color: #fff;
}
class="box">
class="l">type="text">
class="r" type="button" value="百度一下">
// 获取元素
const $ul = $('.box .l ul'),
$input = $('.box .l input')
// 给输入框添加键盘抬起事件
$input.keyup(function () {
// 跨域请求
$.ajax({
url: 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web',
// jsonp方式
dataType: 'jsonp',
// 设置参数值为cb
jsonp: 'cb',
// 设置参数
data: {
wd: $(this).val()
},
// 使用返回的数据到ul上
success: function (data) {
// 判断数据是否存在
if (data.g === undefined) {
return
}
// 调用模版引擎,把生成的结果添加到ul上
$ul.html(template('tem', data))
}
})
})
复制代码
案例:留言板
lang="en">
charset="UTF-8">
name="viewport" content="width=device-width, initial-scale=1.0">
Document
rel="stylesheet" href="css/index.css">
class="main">
class="post">
新年快乐
class
="author">楼主:行痴
class
="txt">新的一年,祝大家新年快乐,身体健康,升职加薪!
class="reply">
发表回复用户名:type="text" class="reply">class="editor">type="button" value="发表" class="btn">
class="cmts">
class="list">
// 获取元素
const $list = $('.main .cmts .list'),
$user = $('.reply input:text'),
$textarea = $('.reply textarea'),
$btn = $('.reply .btn')
// 初始化,使用get获取数据,调用模版引擎修改留言板列表
$.get('http://localhost:3000/db', function (data) {
$list.html(template('tem', data))
// 调用函数给每个删除按钮添加删除功能
del()
})
// 发表按钮点击事件
$btn.click(function () {
// 先判断是否为空,如果为空提示用户
if ($user.val() === '' || $textarea.val() === '') {
alert('输入不正确')
return
}
// 如果不为空执行下面的代码
// 使用pose方法向数据库添加数据
$.post('http://localhost:3000/comments', {
username: $user.val(),
content: $textarea.val()
}, function (data) {
// 返回的数据代入模版,但是模版需要是一个对象并且对象需要有一个comments属性的数组,所有手动模拟对象
$list.append(template('tem', {
comments: [data]
}))
// 新添加的删除按钮没有删除功能,我们在这里给全部删除按钮调用函数重新添加删除功能
del()
})
})
// 删除按钮啊添加删除功能函数
function del() {
// 给每一个按钮添加点击事件
$('.delete').click(function () {
// 从数据库里面删除数据,找到删除按钮的祖先li标签,根据li标签的自定义属性值删除元素
$.ajax({
url: `http://localhost:3000/comments/${$(this).parents('li').attr('uid')}`,
type: 'delete'
})
// 找到删除按钮的祖先的li标签,删除它
$(this).parents('li').remove()
})
}
复制代码
{
"comments": [
{
"id": 4,
"username": "江江",
"content": "给楼主打call~ +10000"
},
{
"username": "西毒",
"content": "楼主一般",
"id": 6
},
{
"username": "东邪",
"content": "哈哈哈哈",
"id": 7
}
]
}
复制代码