2016-09-07 35 views
1

我正在使用rails 5和remotipart。該remotipart版本是:ujs + remotipaart - 運行jQuery`.html(...)`調用時,附加的html變成文本

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

(在這個問題的時刻,當前提交的88d9a7d55bde66acb6cf3a3c6036a5a1fc991d5e)。

當我想提交一個有multipart: true and遠程:真的`但沒有發送任何附加文件的表格,它的工作很好。但是當我發送一個文件時,它失敗了。

爲了說明的情況下,可以考慮這樣的響應:

(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),形式看起來它預期的(在這種情況下,此後,立即驗證錯誤是正確的發生,並呈現危險的警告是正確的這樣的文字顯示):

enter image description here

然而,當我填的是文件中的字段,並重復完全相同的情況下(完全相同的驗證錯誤),for米看起來相當不同:

enter image description here

如果你能猜到,內容爲文本通過。從服務器接收的實際響應是有點不同:

<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); 

這是我的迴應的實際身體(這是不是一個壞copypaste,但包裹由remotipart實際響應)。

modalErrors功能是相當愚蠢的:

function modalErrors(html) { 
    $('#main-modal > .modal-dialog > .modal-content > .modal-body > .errors').html(html); 
} 

比較jQuery的附加HTML塊(我期待他們在瀏覽器的DOM Inspector),他們是這樣的:

好:

<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 

我在這裏錯過了什麼?我想要的是允許我的resposes在需要時附加html內容。

回答

1

remotipart lib使用了一些名爲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 -in不同的場景被送到這兩個觀點,我均值只需更換j CAL ls與jh調用。例如:

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

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