我正在使用 Rails 5,带有 remotipart。远程部分版本是:
gem 'remotipart', github: 'mshibuya/remotipart'
(在提出这个问题时,当前提交是 88d9a7d55bde66acb6cf3a3c6036a5a1fc991d5e)。
当我想提交具有 multipart: true 和
remote: true` 的表单但不发送任何附加文件时,效果很好。但是当我发送文件时,它失败了。
为了说明这种情况,请考虑如下响应:
(function() {
modelErrors('<div class=\'alert alert-danger alert-dismissible\' role=\'alert\'>\n <div aria-label=\'Close\' class=\'close fade in\' data-dismiss=\'alert\'>\n <span aria-hidden>\n ×\n <\/span>\n <\/div>\n Code can\'t be blank\n<\/div>\n');
}).call(this);
当这个响应被执行时,在到达后立即(因为它是js),表单看起来就像它预期的那样(在这种情况下,这个验证错误是正确的发生,并且呈现的危险警报是正确的出现这样的文本):
但是,当我填写文件字段并重复完全相同的情况(完全相同的验证错误)时,表单看起来完全不同:
如果您能猜到,内容将以文本形式传递。从服务器收到的实际响应有点不同:
<script type="text/javascript">try{window.parent.document;}catch(err){document.domain=document.domain;}</script>(function() {
modelErrors('<div class=\'alert alert-danger alert-dismissible\' role=\'alert\'>\n <div aria-label=\'Close\' class=\'close fade in\' data-dismiss=\'alert\'>\n <span aria-hidden>\n ×\n <\/span>\n <\/div>\n Code can\'t be blank\n<\/div>\n');
}).call(this);
这是我响应的实际正文(这不是一个糟糕的复制粘贴,而是由 remotipart 包装的实际响应)。
modalErrors
函数非常愚蠢:
function modalErrors(html) {
$('#main-modal > .modal-dialog > .modal-content > .modal-body > .errors').html(html);
}
比较 jQuery 附加的 html block (我在浏览器的 DOM 检查器中查找它们),它们看起来像这样:
好:
<div class="alert alert-danger" role="alert">
<ul style="list-style-type: none">
<li>Code can't be blank</li>
</ul>
</div>
坏:
Code can't be blank
我在这里缺少什么?我想要的是允许我的回复在需要时附加 html 内容。
最佳答案
remotipart
lib 使用名为 iframe-transport
的内容,稍后解开内容并执行响应,就像使用 ajax 获取一样。
但是,标签会从响应中删除,因此响应将转换为如下内容:
try{window.parent.document;}catch(err){document.domain=document.domain;}(function() {
modelErrors('\n \n \n ×\n \n \n Code can\'t be blank\n\n');
}).call(this);
我发现以合理的方式与该库交互的解决方案是定义另一个辅助助手,类似于 j
/escape_javascript
:
module ApplicationHelper
JS_ESCAPE_MAP = {
'\\' => '\\\\',
'<' => '\\u003c',
'&' => '\\u0026',
'>' => '\\u003e',
"\r\n" => '\n',
"\n" => '\n',
"\r" => '\n',
'"' => '\\u0022',
"'" => "\\u0027"
}
JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = '
'
JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = '
'
def escape_javascript_with_inside_html(javascript)
if javascript
result = javascript.gsub(/(\\|\r\n|\342\200\250|\342\200\251|[\n\r<>&"'])/u) {|match| JS_ESCAPE_MAP[match] }
javascript.html_safe? ? result.html_safe : result
else
''
end
end
alias_method :jh, :escape_javascript_with_inside_html
end
在容易被常规 ajax 和 remotipart 发送的 View 中 - 在不同的场景中,我的意思是 - 只需将 j
调用替换为 jh
调用即可。示例:
modalErrors('<%= j render 'shared/model_errors_alert', instance: @team %>')
被替换为
modalErrors('<%= jh render 'shared/model_errors_alert', instance: @team %>')
关于ruby-on-rails - ujs + remotipaart - 运行 jQuery `.html(...)` 调用时,附加的 html 变为文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39374113/