Javascript Rails:如何使用客户端AJAX请求转义Java脚本
当我通过Javascript Rails:如何使用客户端AJAX请求转义Java脚本,javascript,jquery,ruby-on-rails,ruby,ajax,Javascript,Jquery,Ruby On Rails,Ruby,Ajax,当我通过将集合从控制器操作直接从客户端发送到_json时,如何转义集合 当我说请求从控制器操作发送,然后直接发送到客户端(跳过预处理)时,看起来是这样的: AJAX请求被路由到控制器操作 控制器操作通过javascript直接将结果发送给请求者,请求者的javascript将在客户端进行处理。类似于:app/assets/javascripts/blogs.js 这与将请求发送到控制器_操作,然后发送到服务器端视图进行预处理,然后将结果发送到请求者不同。看起来像这样: AJAX请求 路由
将集合从控制器操作直接从客户端发送到_json
时,如何转义集合
- 当我说请求从控制器操作发送,然后直接发送到客户端(跳过预处理)时,看起来是这样的:
- AJAX请求被路由到控制器操作
- 控制器操作通过javascript直接将结果发送给请求者,请求者的javascript将在客户端进行处理。类似于:
app/assets/javascripts/blogs.js
- 这与将请求发送到控制器_操作,然后发送到服务器端视图进行预处理,然后将结果发送到请求者不同。看起来像这样:
- AJAX请求
- 路由到控制器操作
- 发送到视图进行预处理。类似于:
app/views/blogs/index.js.erb
- 结果将发送给请求者
def some_action
@blogs = Blog.all
respond_to do |format|
format.json {render json: @blogs} # currently dangerous, @blogs is not sanitized.
end
end
例如:假设该集合中的一个@blog
记录有黑客输入的数据:
@blogs.first.title
=> <script>alert('Site now hacked if this javascript runs!')</script>
上面:我关心的部分是
value.id
和value.title
。如果我不逃脱,这些事情可能会很危险。我想确保它被转义,这样任何危险的输入都将变得无害。您正在处理一个未初始化的HTML字符串,就像其他字符串一样。在将其插入页面之前,您需要确保其安全。您真正需要做的就是将
字符替换为
和
以该控制器为例:
class SomethingController < ApplicationController
def jsontest
render json: { blogs: ["<script>alert(1);</script>"] }
end
end
class-SomethingController
如果您不介意笨重,jQuery可以为您做到这一点:
$.ajax({
type: 'GET',
url: '/something/jsontest',
dataType: 'json',
success: function (data) {
console.log($('<div>').text(data['blogs'][0]).html());
}
})
> <script>alert(1);</script>
$.ajax({
键入:“GET”,
url:“/something/jsontest”,
数据类型:“json”,
成功:函数(数据){
console.log($('').text(数据['blogs'][0]).html();
}
})
>脚本警报(1)/剧本
您还可以在控制器端使用
ActionView::Helpers::SanitizeHelper#sanitize
,这将删除它找到的任何HTML标记。(通常这只对视图可用,因此您可以创建一个视图来呈现JSON,也可以在控制器中包含ActionView::Helpers::SanitizeHelper)。或者两者都做 下面是一个解决方案。请记住,在数据被持久化到数据库之前对其进行清理通常是个好主意。另外:最好在向请求者发送响应之前对服务器端进行清理:
app/assets/javascripts/blogs.js
$("body").on('change', '[data-action="blogger_sel"]', function() {
var blogs_selection = $(this).closest('[data-parent-for="blogs_sel"]').find('[data-action="blogs_sel"]');
$.ajax({
url: "/blogs",
type: "GET",
data: {blogger_id: $(this).val()},
success: function (data) {
blogs_selection.children().remove();
$.each(data, function (index, item) {
blogs_selection.append('<option value=' + item.id + '>' + item.title + '</option>');
});
}
})
});
$("body").on('change', '[data-action="blogger_sel"]', function() {
var blog_sel = $(this).closest('[data-parent-for="blog_sel"]').find('[data-action="blog_sel"]');
$.ajax({
url: "/blogs",
type: "GET",
data: {blogger_id: $(this).val()},
success: function (data) {
blog_sel.children().remove();
$.each(data, function (index, item) {
blog_sel.append($('<option>', {
value: item.id,
text : item.title
}));
});
}
})
});
$(“body”)。关于('change','data action=“blogger_sel”]”,函数(){
var blog_sel=$(this).closest(“[data parent for=“blog_sel”]”)。find(“[data action=“blog_sel”]”);
$.ajax({
网址:“/blogs”,
键入:“获取”,
数据:{blogger_id:$(this.val()},
成功:功能(数据){
blog_sel.children().remove();
$。每个(数据、功能(索引、项目){
博客选择附加($(''){
值:item.id,
文本:item.title
}));
});
}
})
});
不要以以下方式附加选项,因为它将执行危险的黑客攻击:
blogs_selection.append('<option value=' + value.id + '>' + value.title + '</option>');
blogs\u selection.append(“”+value.title+“”);
谢谢您的回答。我试图让它为我的例子工作,但我有困难。为了尝试应用您的解决方案:显示:value.title
,我尝试将您的客户端设置为:value.title.html()
,但它似乎不起作用。您需要这样做:$('').text(value.title.html())
重要的部分是通过jQuery在内存中创建div
对象。