6

Scenario: User visits a visualforce page and a few parameters are fed into the page markup to dynamically populate a "plain text" body. This plain-text file is downloaded & executed by the user's browser - launching the local app which handles the named file's extension.

Specifically, I am delivering an SAP shortcut which will open the SAP GUI client installed on the user's local machine. The following code behaves properly in all browsers except for Internet Explorer (8+) which is the environment I am trying to solve for.

The body of the text file is as follows:

[System]
Name=ABC
Description=ABC Development
Client=100
[User]
Language=EN
[Function]
Title=Create Sales Order: Step 1
Command=VA01 VBAK-AUART={param};VBAK-VKORG=US01; VBAK-VTWEG=01;
[Options]
Reuse=1

I came across quite a few articles similar to this one which specifically IE8's file handling behavior from VF but so far I have been unsuccessful in getting the file to launch with the registered application handler for the "*.sap" file type. How do I use Visualforce to generate a CSV file that can be downloaded using IE8?

My controller looks like this - attempting to set the content-disposition header to force the browser to download the file rather than opening it as a page:

public with sharing class myTestController {
    public myTestController() {
            // modified casing per Daniel's commment
        ApexPages.currentPage().getHeaders().put('Content-Disposition', 'attachment; filename=CoolFileName.sap');
    }
}

My page markup (currently) looks like this:

<apex:page controller="myTestController" showHeader="false" sidebar="false" contentType="text/plain#SomeCoolFileName.sap" cache="true" standardStylesheets="false">[System]
Name=ABC
Description=ABC Development
Client=100
[User]
Language=EN
[Function]
Title=Create Sales Order: Step 1
Command=VA01 VBAK-AUART={!$CurrentPage.Parameters.OrderType};VBAK-VKORG=US01; VBAK-VTWEG=01;
[Options]
Reuse=1
</apex:page>

The problem that I run into is that no matter the value that is in the contentType attribute on the page tag, IE8 will always render it as plain text directly in the browser rather than opening it with the application which has been registered with the OS to open ".sap" files. Chrome and Firefox both download and execute the file using the registered handler and the SAP GUI app is launched as desired.

I've attempted to use contentType value of: text/plain, application/octet-stream, application/x-sapshortcut, application/x-msdownload, application/pdf, and a few others for the fun of it.

Microsoft's documentation about mime type detection in IE 4+

Anyone dealt with a similar scenario and have any tips?

5
  • On the apex:page, try taking the file name out of the contentType attribute. That looks a bit odd to me with the #filename at the end of it. Apr 9, 2014 at 1:36
  • Also, in the content-disposition, watch out for long file names or special characters that need to be quoted. Check RFC 2138 and 2231. Apr 9, 2014 at 1:37
  • 1
    From Scott Hanselman circa 2003: "There's a HTTP Header called Content-Disposition (case senstitive) that is NOT part of the HTTP standard, but rather it's own Request for Comments, RFC 1806.". Might be worth changing the casing to be on the safe side. Apr 9, 2014 at 1:46
  • @DanielBallinger thanks for the comments! The behavior of IE doesn't differ when the contentType attribute has the suggested filename after the hash. I've attempted it with and without and they both render the text directly in the browser. I've changed my controller to set the Content-Disposition header with the 'proper' casing but I'm currently on a mac and don't have IE handy. I'll follow up on this in the morning.
    – Mark Pond
    Apr 9, 2014 at 7:15
  • I had the same issue back during the original .com boom time with IE5.5. I've been racking my brain to remember the solution and all I can rememeber is it actually had nothing to do with the content-disposition but something else that needed to be added to the header, just cant remember what. Sorry.
    – Francis
    Apr 9, 2014 at 9:28

1 Answer 1

2

Using a contentType of "application/x-unknown" and specifying the desired filename via setting the Content-Disposition header in the controller was key to making this work.

The working solution was the following code:

Controller

public with sharing class SAPGUILauncher {

    public SAPGUILauncher() {
        Apexpages.currentPage().getHeaders().put('Content-Disposition', 'attachment; filename="SAPGUILauncher.sap"');
    }
}

VF

<apex:page controller="SAPGUILauncher" cache="true" contentType="application/x-unknown">[System]
Name={!$Setup.SAPLauncherSettings__c.SAPName__c}
Description={!$Setup.SAPLauncherSettings__c.SAPDescription__c}
Client={!$Setup.SAPLauncherSettings__c.SAPClient__c}
[User]
Language={!$Setup.SAPLauncherSettings__c.SAPLanguage__c}
[Function]
Title={!$Setup.SAPLauncherSettings__c.SAPTitle__c}
Command=ZSFDCVA01_2 P_AUART={!$CurrentPage.Parameters.OrderType}; P_VKORG={!$CurrentPage.Parameters.SalesOrg}; P_VTWEG={!$CurrentPage.Parameters.DistributionChannel}; P_KUNNR={!$CurrentPage.Parameters.SoldToParty}; P_KUNWE={!$CurrentPage.Parameters.ShipToParty}; P_BSTKD={!$CurrentPage.Parameters.PONumber}; P_MATNR={!$CurrentPage.Parameters.MaterialNumber}; P_KWMENG={!$CurrentPage.Parameters.Quantity};
[Options]
Reuse={!$Setup.SAPLauncherSettings__c.SAPReuse__c}
</apex:page>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .