Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have a helper Apex page to be included in custom button as Javascript. The page is the following:

<apex:page contentType="text/javascript" contorller="HelperController">
function initialize() {
    return {!dataFromController};
}
</apex:page>

I use it in custom button javascript:

{!REQUIRESCRIPT("/apex/MyHelperPage")}
var initResult = initialize(); ....

It works fine, but when I type https://XYZ.salesforce.com/apex/MyHelperPage I see my javascript file as it, not an empty page. So my question: is there a way to include VisualForce page to custom button's javascript but avoid showing its content with direct navigation.

share|improve this question
    
Hey minige, when posting multi-line code snippets the easiest way to mark them as code is to just put four spaces at the start of each line, rather than using backticks. The easiest way to put the spaces in is to just type/paste the code, then highlight it all and hit the {} button :) –  LaceySnr Feb 12 at 4:30
    
JavaScript can't be hidden, only obfusucated/encrypted. That would only frustrate an expert hacker but protect your script from the average layman. I think the question you should be asking yourself is, "why is this data exposed in a way that I have to find ways to hide it?". –  sfdcfox Feb 12 at 4:37

3 Answers 3

up vote 1 down vote accepted

You could pass a parameter in to make it show the javascript and set that in your requirescript.

<apex:page contentType="text/javascript" controller="HelperController">
<apex:outputPanel layout="none" rendered="{!$CurrentPage.Parameters.jsmode = '1'}">
    function initialize() {
        return '{!dataFromController}';
    }
</apex:outputPanel>
</apex:page>

In the example above you'd just add ?jsmode=1 to your URL like so:

{!REQUIRESCRIPT("/apex/MyHelperPage?jsmode=1")}
share|improve this answer
    
Thanks, this will work too, but my REQUIRESCRIPT is already is used in my package so adding parameter will break backward compatibility. Is there a way to get some context in controller? I mean, can I determine if my page/controller was called in custom button processing? –  minige Feb 12 at 0:31
    
This solution provides no extra benefit; the users interested in viewing the script would naturally view the source for the page and note that the parameter is present, therefore copying and pasting the entire link in the address bar. –  sfdcfox Feb 12 at 4:40
    
The only parameter being passed back that would let you get away with this is referer like sfdcfox mentioned in his answer. It isn't fool proof either, but you could check for the referer like sfdcfox mentions in his answer and use the outputPanel to hide everything else. –  drakored Feb 12 at 4:56

You could check ApexPages.CurrentPage().getHeaders().get('Referer') and make sure this value isn't blank. Browsers normally send a 'Referer' header as an indication to the server that the user requested this resource from another location. However, this header is optional and therefore may break if the browser refuses to send this header, perhaps because of some privacy addon or future changes to the HTTP standard. Conversely, the user could still get at the script simply by checking F12 (Developer Tools) on almost any browser (Chrome, IE...), or through an installed addon. They could also inject a fake link using a JavaScript URL or a console, causing the referer header to appear. Or, they could check their cache files for the script, if they were so inclined. Savvy users could also write a XMLHttpRequest script in a console and get at the script without much effort. In short, you can't reasonably hide your code and make it available for use in your page.

share|improve this answer

You can create a webservice method in a global class and can use that method to retrieve data from the controller as below :

global class HelperController {        
    global static String initilize(){
    /*return data*/    
    }
}

Then you can create a Custom button and call this method using onclick javascript :

var initResult = HelperController .initialize();
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.