2

我正在使用带有remotipart的rails 5。远程版本是:

gem 'remotipart', github: 'mshibuya/remotipart'

(在这个问题的那一刻,当前提交是 88d9a7d55bde66acb6cf3a3c6036a5a1fc991d5e)。

当我想提交一个具有multipart: true andremote: 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      &times;\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      &times;\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 块(我在浏览器的 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 内容。

4

1 回答 1

2

remotipartlib 使用了一些名为的东西iframe-transport,稍后解包内容并执行响应,就好像它是使用 ajax 获取的一样。

但是,标签会从响应中删除,因此响应将被转换为如下内容:

try{window.parent.document;}catch(err){document.domain=document.domain;}(function() {
  modelErrors('\n  \n    \n      &times;\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!] = '&#x2028;'
  JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = '&#x2029;'

  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 发送的视图中 - 在不同的场景中,我的意思是 - 只需将j调用替换为jh调用。例子:

modalErrors('<%= j render 'shared/model_errors_alert', instance: @team %>')

被替换为

modalErrors('<%= jh render 'shared/model_errors_alert', instance: @team %>')
于 2016-09-07T20:50:25.523 回答