Extjs fileuplaod - cross-origin frame

会有一股神秘感。 提交于 2019-11-30 13:59:51

This is a Ext js bug identified by Uberdude in the Sencha Forum.

Description of the problem :

When you make an Ext.Ajax.request with a form containing a file input to be uploaded, or manually set the isUpload option to true, rather than doing a proper Ajax request Ext submits the form in the standard HTML way to a dynamically generated hidden . The json response body is then read out of the iframe to create a faked-up Ajax response. A problem arises if the page making the upload Ajax request has changed its document.domain property, e.g. a page at home.example.com includes resources from static.example.com which it wishes to manipulate with javascript without violating the browser's same-origin-policy, so both set their document.domain to "example.com". If home.example.com then makes an upload Ajax request to a url on the home.example.com server, the iframe into which the response is written will have its document.domain as "home.example.com". Thus when the ExtJS code within Ajax.request on the home.example.com page tries to extract the document body from the iframe, it will be blocked by the same-origin-policy and the response passed to the callback functions will incorrectly have empty responseText.

Work Around : 1. Pass the document.domain to the server when making the upload request. 2. In your server response, add the document.domain in your response text/html.

response.setHeader('Content-Type', 'text/html'); response.write('document.domain = "' + params.__domain + '";'); response.write(JSON.stringify({msg: 'Welcome ' + params.name})); response.end('');

Detail :

Please refer to : http://www.sencha.com/forum/showthread.php?136092-Response-lost-from-upload-Ajax-request-to-iframe-if-document.domain-changed

santrupta

Adding additional comments to Wilk's answer.

If your host and destination are on different port then use below solution.

In the index.html file use the below line under head :

<script type=text/javascript>document.domain =document.domain;</script>

and in your response along with header Content-Type:'text/html' and the response

'<html><head><script type=text/javascript>document.domain =document.domain;</script></head><body>{success: true}</body></html>'

Success message is hard coded here, you can use any custom message based on your input.

Thanks, Santrupta

Wilk

This is an improvement of cheftao answer.

If you need to work with different domains (e.g. localhost with a different port), follow these steps:

on the client side, before submitting the form, renew the document domain and then submit it with the form data:

  document.domain = document.domain;
  myForm.submit({
    params: {
      domain: document.domain
    },
    ...
  });

on the server side, respond with content-type text/html and with the following string (this example is done with ExpressJS):

var domain = req.body.domain,
    script = '<script type="text/javascript">document.domain = "' + domain + '";</script>',
    body = '<body>' + JSON.stringify({success: true}) + '</body>';

res.send('<html><head>' + script + '</head>' + body + '</html>');

Update: 19/05/2016

Actually, the best solution is to do reverse proxy, avoiding this kind of problems.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!