简体   繁体   中英

iFrame not executing javascript from AJAX call

TL;DR: I have an iframe which makes an AJAX call to a Rails app that returns a Javascript response. After upgrading my app from Rails 2.3 to 5.1, the Javascript is now rendered as text inside the iframe instead of executed. Any idea why?

Full details:

My legacy Rails app renders the following partial as the UI for the user to upload a csv file:

<div class="uploadForm" style="">
  <iframe src="/my_controller/upload_file/1" width="320px" height="195px" style="border:none;" scrolling="no" frameborder="0">
  </iframe>
</div>

In Rails 2.3 routes of the form controller#action were dynamically generated, but this turned out to be a security risk; so in the upgraded version I've had to manually specify a route; I removed the trailing /1 , as I have no idea what it was doing and it didn't appear to be needed. The action my_controller#upload_file simply renders the following partial:

<!--stylesheet link/>

<% form_tag( url_for(:controller=>'my_controller', :action => 'csv_import',:previous_window => 'window.opener' ), :multipart => true) do %>
<input id='file_upload' name='file' size='20' type='file' />
<%= submit_tag 'OK' %>
 #radio buttons
<% end %>

On submission, the form is processed by the action my_controller#csv_import :

def csv_import
 #code that handles parsing csv
 render :partial => "return_file"
end

In the legacy app, the partial _return_file.rhtml (told you it was legacy!) looked like (slightly simplified)

<script>
 alert("Successfully processed <%= @added %> rows")
</script>

which executed fine. However, trying this same thing in my 5.1 app (renaming the .rhtml to .html.erb ) doesn't work, instead rendering the text (script tags and all) inside my iframe. I tried instead changing it to a .js.erb extension, using

render :partial => "return_file", formats: :js

as I'm using everywhere else I want to return Javascript in the project, but get the same result. I have literally no idea why, and none of the other answers about JS in iFrames seem relevant to this case, so any help would be enormously appreciated.

EDIT: In response to Sikandar Tariq's answer below, I compared the response headers for the old and new versions of my site, and found that the new version added the following headers:

X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:879d2d21-b1fa-43e8-8e03-6cd5e78ef72f
X-Runtime:0.403123
X-Xss-Protection:1; mode=block

My guess is that the last term is the one that's causing me grief, and it somehow mistakenly identifies a XSS attack so it displays the response as plain text instead of rendering it. But why would it erroneously flag this when X-Frame-Options is set to SAMEORIGIN ? I mean, I know that iframes are regarded in most contexts as a separate domain, but isn't the X-Frame-Options designed specifically for iframes?

EDIT EDIT: I added the following lines of code to my controller before calling render.

response.headers["X-XSS-Protection"] = "0"
response.headers.delete('X-Frame-Options')

My problem persists. I've checked that these lines have taken effect in the response.

iframs act as different website/domains, so calling ajax from iframe is like cross-domain execution which is not allowed for the sake of security. See same-origin policy for more information

So, I found a way of fixing this. I have literally no idea why it works, so any helpful advice or explanations would still be received with gratitude and upvotes. When the steps outlined in my edits to the post didn't work, I first of all decided to remove all response headers that related to XSS:

response.headers.keys.each do |header|
  response.headers.delete(header) if header =~ /X-/
end

I decided that this was safe as no user-supplied data is getting passed to the view, just some integers I've calculated based on user supplied data; this may not be a safe option for you.

Then, bizarrely, I had to get rid of rendering the call to render the response as Javascript, and instead render html and wrap my Javascript in <script> tags.

Like I said, this is posted in case it helps anyone else, but if anyone has anything to add I'd be grateful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM