今天是我们最后一天ajax的学习,这次学完总可以去vue了吧,我不信还有什么拦路石,先不说其他的先看看今天的内容。
1.
首先是同源策略,什么叫做同源?
如果两个页面的协议、域名、端口都相同的话,我们将这两个页面为同源。
那么什么同源策略呢?
是浏览器提供的一个安全功能,如果说两个页面不同源,那么A网站就无法读取B网站的cookie、localstorage、indexdb等;无法接触B网站的DOM;无法向B网站发送ajax请求
了解了同源与他相反的就是跨域,也就是上面说的协议。域名、端口只要有一个不满足那么他们就是跨域。
浏览器对跨域请求的拦截,我们是能够正常发起对服务器的请求的,服务器也能够感应到请求并将数据返回回来,但是就在临近城门的时候,在浏览器门口就被一个同源策略的门卫拦截住了,一生之敌。
那么既然如此如何来实现跨域的请求呢?有两个方式CORS和JSONP。
cors是w3c标准支持get和post
JSONP
原理:由于浏览器同源策略的限制,网页无法通过ajax请求非同源,但是script这个标签是不受限制的,所以可以通过src这个属性请求到非同源的script
实现::自己定义一个回调函数,然后通过另一个script标签的src属性来调用服务器和一些参数在这个参数里面callback=这个函数的名字就是你自己回调函数的名字然后后面跟上你自己的参数
<!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>
</head>
<body>
<script>
function fn(data) {
console.log('调用成功');
console.log(data);
}
</script>
<script src="http://www.liulongbin.top:3006/api/jsonp?callback=fn&name=张三&age=29&sex=男"></script>
</body>
</html>
JSONP的缺点就是他只支持get请求
2.
jQuery中的JSONP,具体的格式如下
<!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>
</head>
<body>
<button>点击查看jsonp</button>
<script src="../day01/lib/jquery.js"></script>
<script>
$('button').on('click', () => {
$.ajax({
url : 'http://www.liulongbin.top:3006/api/jsonp?name=张三&age=29&sex=男',
dataType : 'jsonp',
jsonpCallback : 'fn',
success : res => console.log(res)
})
})
</script>
</body>
</html>
在这里面datatype必须制定,然后url中没有了callback,因为他会自己随机生成一个callback,你也可以自己修改,jsonpCallback是修改回调函数名字的,jsonp是修改callback的。
在jq中jsonp的一个运行过程也要知道一下,他其实也是依靠script标签来实现的,在请求的时候他会动态生成一个script标签在header,然后请求完成又会移出这个标签。
3.
这些都学完了就可以看到一个案例,模仿淘宝的搜索关键字案例
<!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" />
<!-- 导入 jQuery -->
<script src="./lib/jquery.js"></script>
<!-- 3.1插入template 准备用到模板引擎 -->
<script src="./lib/template-web.js"></script>
<!-- 3.2定义ui结构 -->
<script type="text/html" id="suggestList">
{{each result}}
<div class="suggest-item">{{$value[0]}}</div>
{{/each}}
</script>
<style>
.suggest-list {
display: none;
border: 1px solid #ccc;
}
.suggest-item {
padding-left: 5px;
line-height: 30px;
}
.suggest-item:hover {
cursor: pointer;
background-color: #eee;
}
</style>
</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" class="ipt" placeholder="请输入要搜索的内容" /><button class="btnSearch">
搜索
</button>
</div>
<!-- 3.在搜索框下面添加一个盒子拿来装关键字列表 -->
<div class="suggest-list">
</div>
</div>
</div>
<script src="./lib/jquery.js"></script>
<script src="./lib/index.js"></script>
</body>
</html>
通过jsonp和前面说到的模板引擎来实现
$(function() {
// 1.先获取输入框的文字
$('.ipt').on('keyup', function(e) {
let iptText = $(this).val().trim()
if (iptText == '') {
// 4.搜索关键词为空时需要隐藏搜索列表
return $('.suggest-list').empty().hide()
} else {
// 2.1调用获取关键字函数
getSearchList(iptText)
}
})
// 2.封装获取建议列表的函数
function getSearchList(text) {
$.ajax({
url : 'http://suggest.taobao.com/sug?q='+text+'',
dataType : 'jsonp',
success : res => {
getHtml(res)
}
})
}
// 3.3调用函数并渲染
function getHtml(res) {
if (res.result.length <= 0) {
return $('.suggest-list').empty().hide()
} else {
let htmlStr = template('suggestList', res)
console.log(htmlStr);
$('.suggest-list').html(htmlStr).show()
}
}
})
4.
防抖
防抖策略就是当一个事件被触发后,延迟几秒在执行回调函数,如果在这几秒内又被触发了,那么就会重新计时
主要应用场景在用户输入时连续输入一串字符,可以通过防抖策略只有在输入完毕过后再去执行查询的请求这样可以有效减少请求次数。
具体怎么来实现需要一个定时器,然后定义防抖函数,这个函数里面开启定时器获取jsonp数据渲染html都在这里面调用,在用户键盘事件这里清除定时器,输入一个清除一个输入一个清除一个,所以只要输入的够快,就达不到进入执行这个定时器的门槛,当你停下输入正常执行代码,就会开始执行定时器,去调用去请求去渲染

$(function() {
// 防抖1 定义一个延时器
var timer = null
// 防抖2 定义防抖函数
function debounceSearch(text) {
timer = setTimeout(() => {
getSearchList(text)
}, 500);
}
// 1.先获取输入框的文字
$('.ipt').on('keyup', function(e) {
// 防抖3一进来先清除定时器,按一下清一下
clearTimeout(timer)
let iptText = $(this).val().trim()
if (iptText == '') {
// 4.搜索关键词为空时需要隐藏搜索列表
return $('.suggest-list').empty().hide()
} else {
// 2.1调用获取关键字函数
// getSearchList(iptText)
// 防抖4 调用获取关键字函数由定时器执行相当于等你输完了在执行
debounceSearch(iptText)
}
})
// 2.封装获取建议列表的函数
function getSearchList(text) {
$.ajax({
url : 'http://suggest.taobao.com/sug?q='+text+'',
dataType : 'jsonp',
success : res => {
getHtml(res)
}
})
}
// 3.3调用函数并渲染
function getHtml(res) {
if (res.result.length <= 0) {
return $('.suggest-list').empty().hide()
} else {
let htmlStr = template('suggestList', res)
console.log(htmlStr);
$('.suggest-list').html(htmlStr).show()
}
}
})
缓存搜索
就是当我们输入一个数据的时候又添加一个关键字,然后删了有输入第一个关键字这个时候请求了三次,其中第一次和第三次是重复的,怎么解决
先定义一个全局的缓存对象,将搜索结果缓存到缓存对象中,优先从缓存中获取数据.
$(function() {
// 防抖1 定义一个延时器
var timer = null
// 防抖2 定义防抖函数
function debounceSearch(text) {
timer = setTimeout(() => {
getSearchList(text)
}, 500);
}
// 缓存1 定义一个全局空对象
var resObj = {}
// 1.先获取输入框的文字
$('.ipt').on('keyup', function(e) {
// 防抖3一进来先清除定时器,按一下清一下
clearTimeout(timer)
let iptText = $(this).val().trim()
if (iptText == '') {
// 4.搜索关键词为空时需要隐藏搜索列表
return $('.suggest-list').empty().hide()
} else {
// 缓存3 当我们输入值得时候就去判断一下有没有对象里有没有该值如果有那直接渲染就是不用再去请求数据
if (resObj[iptText]) {
getHtml(resObj[iptText])
} else {
// 2.1调用获取关键字函数
// getSearchList(iptText)
// 防抖4 调用获取关键字函数由定时器执行相当于等你输完了在执行
debounceSearch(iptText)
}
}
})
// 2.封装获取建议列表的函数
function getSearchList(text) {
$.ajax({
url : 'http://suggest.taobao.com/sug?q='+text+'',
dataType : 'jsonp',
success : res => {
console.log(res);
getHtml(res)
}
})
}
// 3.3调用函数并渲染
function getHtml(res) {
if (res.result.length <= 0) {
return $('.suggest-list').empty().hide()
} else {
let htmlStr = template('suggestList', res)
// console.log(htmlStr);
$('.suggest-list').html(htmlStr).show()
// 缓存2 一切获取数据输入完毕在这里获取输入的最终值保存进对象里
resObj[$('.ipt').val().trim()] = res
}
}
})
5.
节流
节流策略就是可以减少一段时间事件的触发频率,通过一个节流阀达到本不需要这么高的触发率,让资源空出来
<!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>
html,body {
margin: 0;
padding: 0;
}
img {
position: absolute;
}
</style>
</head>
<body>
<img src="./angel.gif" alt="">
<script>
/* 普通版
var img = document.querySelector('img')
document.onmousemove = function(e) {
// console.log(11);
img.style.left = e.pageX + 'px'
img.style.top = e.pageY + 'px'
} */
// 节流版
var img = document.querySelector('img')
var timer = null
document.onmousemove = function(e) {
// console.log(11);
if (timer) {
return
} else {
timer = setTimeout(function() {
img.style.left = e.pageX + 'px'
img.style.top = e.pageY + 'px'
timer = null
},16)
}
console.log(11);
}
</script>
</body>
</html>
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。有没有学习Ajax(jQuery)和Rails3的好资源?
我正在使用一个用RubyonRails构建的应用程序,目前错误处理非常差。如果通过ajax执行Controller方法,并且该方法导致500(或404或任何其他响应),则呈现500.html页面并将其作为AJAX请求的结果返回。显然,javascript不知道如何处理该HTML,网页看起来只是在等待响应。在AJAX调用期间发生错误时,rails是否有一种简单的方法来呈现error.rjs模板? 最佳答案 您可以在Controller的rescue_action或rescue_action_in_public方法中使用respond_
我正在使用Rails4.0。我正在发送这样的事件(注意:remote=>true):true,:class=>"rate-btnyes-btnbtnbtn-defaultbtn-sm"}%>我的Controller看起来像这样:defratevideo=Video.find_by(hashed_id:params[:id])action=params[:yesno]putsvideo.hashed_idputsactionrespond_todo|format|if(action=='yes')new_rating=video.rating==1?0:1video.update(is_
如果我有一个链接-=link_to'ajaX',ajax_delete_link_path(link),data:{:confirm=>'Areyousure?',:remote=>true}有一条路线:get'ajax_delete_link/:id',to:'links#ajax_delete_link',as::ajax_delete_link和一个链接Controller:defajax_delete_link@link=Link.find(params[:id])@link.destroyrespond_todo|format|format.jsendend和ajax_del
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭11年前。我认为acts_as_rateable似乎已经过时并且不支持AJAX。我正在寻找一个简单的“5星”评级系统:是否有任何插件或教程可以提供帮助?
是否有可能为ajax通信修改设计SessionsController?编辑我找到了解决方案,并将其发布到答案中,谢谢 最佳答案 1。生成DeviseController以便我们修改它railsgdevise:controllers现在我们在app/controllers/[model]目录中拥有所有Controller2。编辑routes.rb让我们将Devise设置为使用我们修改后的SessionsController首先将此代码(当然将:users更改为您的设计模型)添加到config/routes.rbdevise_for:u
我想测试我的Controller操作是否正在渲染部分内容。我四处寻找,似乎找不到任何有用的东西。创建Action:defcreate@project=Project.new...respond_todo|format|if@project.saveformat.js{render:partial=>"projects/form"}endendend规范:it"shouldsaveandrenderpartial"do....#Iexpected/hopedthiswouldworkresponse.shouldrender_partial("projects/form")#oreven