5

Okay so I'm getting this weird unexpected response from Internet Explorer, while testing file upload with smarty in php.

Here my smarty code for file upload (view), simplified down to main issue, for those who have not used activecollab the Router::assemble is just forming a url with parameters that are read from the MVC.

interface
(source: iforce.co.nz)

 <div id="xero_invoice_manager_api">
 {form action=Router::assemble('xero_invoice_manager_api') method=post id="xero_invoice_manager" enctype="multipart/form-data"}
 <div class="content_stack_wrapper">

 <input type="file" name="file_1" /><br/>
 <input type="file" name="file_2" /><br/>
 {wrap_buttons}
 {submit success_event="api_updated" }Authenticate{/submit}
 {/wrap_buttons}
 {/form}
 </div></div>

And here is my jquery for the view.

 App.Wireframe.Events.bind('api_event_finished.content', function(event, settings) {
App.Wireframe.Flash.success(App.lang('Xero Invoice Manager has saved/uploaded your Xero API data.'));
 });

Here is my simplified controller (I have found the issue is with smarty and not php).

//api view
function api(){
    if ( $this->request->isSubmitted()) {
        $this->response->respondWithData(true);
    }
}

Here is my controller with the upload occuring..

//api view
function api(){
    $this->assignSmarty();
    if ($this->request->isSubmitted()) {
        $this->XeroAuthUpdate(); //update everything
        if(isset($_FILES)){
            $file_manager = new XeroFileManager();
            $file_manager->dumpFiles($_FILES);
            //upload the files
            foreach($_FILES as $file){
                $file_manager->handle_certificate_file($file);
            } //foreach add the headers
            if(function_exists('headers_list')){
                xeroDebugMode("[Controller] the headers to be sent are... ", headers_list());
            } //function check
        } //end if
        $this->response->respondWithData(array(
           // constraints
           'key_result'           => (bool)$this->checkValue(XeroAuths::getSetting('xero_consumer')),
           'secret_result'        => (bool)$this->checkValue(XeroAuths::getSetting('xero_secret')),
           // files secruity certificates
           'publickey'            =>  (bool)file_exists(XERO_PUBLIC_KEY_PATH),
           'privatekey'           =>  (bool)file_exists(XERO_PRIVATE_KEY_PATH),
           'xero_auth'            =>  (bool)validateXeroAuth(),
           //login constraints
           'install'              => !$this->checkInstallRequirements(),
        ));
    } //close the request
}

Here is a response from firefox with the file_1 and file_2 not empty.

firefox
(source: iforce.co.nz)

Here is a response from internet explorer 9 with file_1 and file_2 empty (so far so good).

ie empty
(source: iforce.co.nz)

Here is the problematic response from internet explorer 9 with file_1 (i.e. publickey.cer) and file_2 (i.e. privatekey.pem) not empty (download index.php huh?).

not empty
(source: iforce.co.nz)

My response from activecollab

Hello Micheal,

Sorry for the late reply.

Unfortunately we cannot figure out where the problem is. It looks like everything is written OK but without dealing with the code itself there's pretty much nothing we can do. Dealing with JSON responses in IE works fine across activeCollab (well, not in IE6) since almost everything in aC 3 is based on JSON, which makes your issue specific and probably there's something wrong in your code.

Regards, Oliver Maksimovic activeCollab development & support

General and Pre-Sale Questions: 1-888-422-6260 (toll-free) Technical Support: support@activecollab.com

An associate has suggested..

Would suggest trying the following though: 1) open IE -> open the developer tools (press F12) -> Click "Cache" in menu -> click "Clear Browser Cache"... When thats finished click "Cache" and then click "Always refresh from server".

this forces IE to not cache anything, as I've had numerous times where IE was caching ajax requests and causing some very strange behaviour.

let me if this fixes your problem, and if so we can add some php to your ajax response to force all browsers to never cache the response. otherwise if that still doesn't work, probably need to do some JS debugging in IE, to see what's being sent and compare it to your FF firebug results.

headers_sent() comes up blank

but the headers_list (just before respondWithData is called), for Internet Explorer.

2012-08-08 06:50:16 the headers sent from this request is... Array
(
    [0] => X-Powered-By: PHP/5.3.8
    [1] => Set-Cookie: ac_activeCollab_sid_yhRk0xSZku=1%2Fhkykz0Rw0796e4lDykXekNXvhMMxC8pV4akJPMvA%2F2012-08-08+06%3A50%3A15; expires=Wed, 22-Aug-2012 06:50:15 GMT; path=/
    [2] => Content-Type: application/json
    [3] => Expires: Mon, 26 Jul 1997 05:00:00 GMT
    [4] => Cache-Control: no-cache, no-store, must-revalidate
    [5] => Pragma: no-cache
)

Response Headers from Raw tab on Fiddler, on Internet Explorer

HTTP/1.1 200 OK
Date: Sat, 11 Aug 2012 08:08:46 GMT
Server: Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By: PHP/5.3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie:   ac_activeCollab_sid_yhRk0xSZku=11%2Fz8rWxiRchAh8EWinYO2d7a1mmvn2DMKUdse1vfKh%2F2012-08-11+0    8%3A08%3A46; expires=Sat, 25-Aug-2012 08:08:46 GMT; path=/
Content-Length: 107
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8

 {"key_result":true,"secret_result":true,"publickey":true,"privatekey":true,"xero_auth":true,"install":true}

Response Headers from Raw tab on Firefox.

HTTP/1.1 200 OK
Date: Sat, 11 Aug 2012 08:13:45 GMT
Server: Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By: PHP/5.3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: ac_activeCollab_sid_yhRk0xSZku=12%2FO40CbXC9Vfa7OVnderlK2MFnvnpkyeckvO0Ab5NQ%2F2012-08-11+08%3A13%3A45; expires=Sat, 25-Aug-2012 08:13:45 GMT; path=/
Content-Length: 107
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8

{"key_result":true,"secret_result":true,"publickey":true,"privatekey":true,"xero_auth":true,"install":true}

Any ideas on what I'm doing wrong with IE? and why Internet Explorer is notifying the user to download index.php (when the fields are active with values). Keeping in mind that no actual uploading is occurring on the server-side (during the initial test, the index.php download request is irrelevant to move_uploaded_file).

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
classicjonesynz
  • 4,012
  • 5
  • 38
  • 78
  • The index.php, which is being offered by IE for download, is being requested using an iframe, right? If so, you should check the headers IE receives (they may differenciate from the ones you get in Firefox), and check if it has any headers you didn't know of, that might initiate this download. Also, check if the iframe gets redirected to another page, which sends a file for download. – Robbietjuh Aug 08 '12 at 00:07
  • @Robbietjuh hey I've appended the IE headers to the question, Thanks – classicjonesynz Aug 08 '12 at 01:03
  • Can you add the response headers, too? The headers you added are being sent by IE, I'd like to know what is being sent *to* IE – Robbietjuh Aug 08 '12 at 01:06
  • @Robbietjuh I've appended the `headers_list()`. – classicjonesynz Aug 08 '12 at 01:16
  • 1
    Firstly, what is the content IE is recieving? If it's not actually json, maybe IE9 is less tolerant. Secondly, from the ie dev tools, what are the headers IE sees from the response? Headers can be added by apache, too, so just looking at what PHP sends isn't enough. – Hamish Aug 08 '12 at 07:51
  • @Hamish in theory IE is initially receiving `multipart/form-data`. I'll get more information about the responses tomorrow (quite tired) – classicjonesynz Aug 08 '12 at 10:34
  • @Hamish updated question with Internet Explorer response headers. – classicjonesynz Aug 09 '12 at 00:08
  • Heh, those are the request headers.. could you post response headers, and the actual response text? – Hamish Aug 09 '12 at 00:50
  • Do you get the download dialog, when opening the website on a different (fresh?) machine? It could be, that your machine is acting different than a fresh installation... – Robbietjuh Aug 09 '12 at 03:23
  • I've tested it on about 4 different machines, And I'll post the response headers in the afternoon when I'm free :) – classicjonesynz Aug 09 '12 at 22:45
  • @Hamish I've just updated the question with response headers – classicjonesynz Aug 11 '12 at 07:53
  • Hmm, random question - but what if you force HTTP 1.0 instead of 1.1? – Hamish Aug 11 '12 at 23:03
  • When I force `header('HTTP/1.0 200 OK')`, I still get the `index.php` being requested to download. – classicjonesynz Aug 13 '12 at 07:48

3 Answers3

0

Due to the lack of answers, I think I need to take a different approach in my jquery.. until an actual solution is found.

classicjonesynz
  • 4,012
  • 5
  • 38
  • 78
0

It could be that IE specific code has an error, and so the returned content-type is different. If you make an AJAX request for some kind of XML or JSON data and instead get some kind of file HTML error response with a different content-type or disposition than expected, the browser might not know what to do with it.

You might want to find a way to view or log the response (as opposed to request) headers sent by the web server. Usually a prompt for file download comes from a content-disposition header... though in this case it might just be because it's a file coming from an asynchronous request.

You might also want to look at:

IE prompts to open or save json result from server and How can I convince IE to simply display application/json rather than offer to download it?

Community
  • 1
  • 1
nairbv
  • 4,045
  • 1
  • 24
  • 26
  • I have updated my handleIE function to include `header("Content-Type: application/json");` as stated in the links you have provided, but still no luck :(. Regards – classicjonesynz Aug 08 '12 at 06:54
  • Also with [this](http://stackoverflow.com/questions/6114360/stupid-ie-prompts-to-open-or-save-json-result-which-comes-from-server) proposed solution, will each user that has the app have to update their registry in order to get it going? (I kind of want the json to be automated without having to change anything in the registry or windows files). Regards – classicjonesynz Aug 08 '12 at 07:04
  • Well, the registry thing would be more about isolating the issue just checking if it works or not. Even if you set the content-type, if there's any kind of error in your code the web server could change the content type.... like if you got a 500 error I don't think it's going to be the same content type. – nairbv Aug 08 '12 at 16:18
0

I had a similar issue using pupload and mvc3. I know we use different technology but maybe my issue could help you. I had this:

 public JsonResult UploadDoc(string correlationId)
    {
        try
        {

           //upload code here
            return Json(new { message = "chunk uploaded", name = "test" });           

        }
        catch (Exception ex)
        {

            return Json(new { message = "chunk uploaded", name = "test" });  
        }

    }

Now everytime I wanted to try upload a file I would get IE asking me to open or download a file which just contained that json response above. If I set my return type as "String" and set my return code as:

 return "{\"respCode\" : \"200\", \"Msg\" : \"succussful\",\"mimeType\": \"" +  Request.Files[0].ContentType + "\", \"fileSize\": \"" + Request.Files[0].ContentLength + "\"}";

Then the file was successfully uploaded. Response Header for when it failed: "Content-Type: application/json; charset=utf-8" . Response Header for when it works with "String" return type: "Content-Type: text/html; charset=utf-8". Hope it helps, cheers.

jjay225
  • 508
  • 6
  • 12
  • Hey thanks jjay, the activecollab framework uses the [json_encode](http://php.net/manual/en/function.json-encode.php) from PHP, I've also validated the response at [JSONLint](http://jsonlint.com/). Thanks – classicjonesynz Aug 11 '12 at 07:44
  • I've noticed after reading the response headers that the function `$this->response->respondWithData(true);` sets the headers to return, so my module doesn't have any control over it. (my `header('Content-Type: ....` doesn't modify the headers once the code reaches the `respondWithData` function). – classicjonesynz Aug 11 '12 at 08:05