I've an MVC ASP page with the following code:
<script type="text/javascript" src="https://TEST_DOMAIN.com/test.js"> </script>
#*<script type="text/javascript" src="https://LIVE_DOMAIN.com/Live.js"> </script>*#
Essentially I comment or uncomment the script I want to use if the site is Live or if its on Test. I'd love to be able to do this dynamically some how. One solution, perhaps, is if it could read the current URL and figure out if its Live/Test.
Updated with Answer (thanks Whipdancer)
In Web.config I have added the url:
<add key="BundleJS" value="https://TEST_DOMAIN.com/test.js" />
<!--<add key="BundleJS" value="https://LIVE_DOMAIN.com/Live.js" />
I will look into web.config transformations next. But this is much better than what I had before.
The next step was during Session_Start in the Global.asax.cs file I set the url to an application variable:
Application["BundleJS"] = System.Configuration.ConfigurationManager.AppSettings["BundleJS"];
After this was set I was able to go to the controller of the view (Tip: in my case the view was a layout so I went to the parent controller). On or after the ActionResult method I added the Application variable to the viewbag
ViewBag.BundleJS = HttpContext.Application["BundleJS"];
Finally in the cshtml page (which was _layout for me) I set the script up
<script type="text/javascript" src="#ViewBag.BundleJS"> </script>
Since you are using ASP.NET MVC - you can use web config transformations to handle your different environments.
More info on web config transformations
I would then use a web config parameter to determine the appropriate environment, that is loaded via global.asax (or possible in my primary view controller).
You would then be able to automatically determine the appropriate URL based on the environment you compiled to.
in test web.config:
<appSettings>
<add key="JSSource" value="https://TEST_DOMAIN.com/test.js" />
</appSettings>
in release web.config:
<appSettings>
<add key="JSSource" value="https://LIVE_DOMAIN.com/Live.js" />
</appSettings>
in global.asax you could do something like:
public class MvcApplication : System.Web.HttpApplication
{
public static string jsUrl;
protected void Application_Start()
{
jsUrl = System.Configuration.ConfigurationManager.AppSettings["JSSource"];
}
}
In you page you could then use something like this:
<script type="text/javascript" src="#jsUrl"> </script>
** I don't think this code will run as is. It is to give you a general idea.
You can check this answer:
https://stackoverflow.com/a/5819693/2710681
Alternatively, you can test with jQuery's Ajax getScript method but the above is probably better:
if (test) {
$.getScript( "https://TEST_DOMAIN.com/test.js", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Test load was performed." );
});
} else {
$.getScript( "https://LIVE_DOMAIN.com/Live.js", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Live load was performed." );
});
}
Since you are using Razor you could do it server side:
#if(isLive)
{
<script type="text/javascript" src="https://TEST_DOMAIN.com/test.js"> </script>
}
else
{
<script type="text/javascript" src="https://LIVE_DOMAIN.com/Live.js"> </script>
}
where isLive is a variable that indicates if current environment is Test or Live. This solution will run server side and won't pollute the HTML with more scripts
EDIT: If you don't have an environment variable, you could pass a bool object from the controller to the view (using ViewBag), setting to true if it's build in DEBUG, using preprocessor directives.
[Code]
bool isLive = true;
#if DEBUG
isLive = false;
#end if;
your if statement could be
var a = document.createElement('a');
a.href = url;
var hostname = a.hostname;
if(hostname == "yourlivewebsite.com") {
} else {
}
Related
I'm trying to build a application server using scala.js, scalatags, akka-http, and mill as my build tool. All goes well until the browser tries to find scripts with generated scala.js code. This is the scalatags code which successfully gets built and references the compiled scala.js code (HiPage.js - built as a ScalaJSModule in mill). When it is run the println below prints out:
file:/Users/nnovod/projects/lims/LIMS/resources/HiPage.js
which is indeed where I've placed the javascript output from scala.js
object HiPage {
val boot =
"Hi().main(document.getElementById('contents'))"
println(getClass.getResource("/HiPage.js").toString)
val skeleton =
html(
head(
script(`type`:="text/javascript", src:="/HiPage.js"),
link(
rel:="stylesheet",
href:="https://cdnjs.cloudflare.com/ajax/libs/pure/0.5.0/pure-min.css"
)
),
body(
onload:=boot,
div(id:="contents")
)
)
}
This eventually shows up in the browser as follows:
<html>
<head>
<script type="text/javascript" src="/HiPage.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pure/0.5.0/pure-min.css"/>
</head>
<body onload="Hi().main(document.getElementById('contents'))">
<div id="contents"></div>
</body>
</html>
This is my akka-http route...
val route =
path("hello") {
get {
complete(
HttpEntity(
ContentTypes.`text/html(UTF-8)`,
HiPage.skeleton.render
)
)
}
}
The browser can never find the HiPage.js ("Failed to load resource: the server responded with a status of 404 (Not Found)"). HiPage.js is in a top level resources directory and is found by the println(getClass.getResource("/HiPage.js").toString) in the code. What do I have to do to get it seen when the browser requests it from the server?
Not sure if this is the best way but I finally was able to solve the problem by having all src references in script start with /resource and then editing my akka-http route to include the following:
pathPrefix("resource") {
extractUnmatchedPath { unmatched =>
val resource = unmatched.toString()
if (!resource.startsWith("/"))
reject()
else
getFromResource(resource.substring(1))
}
}
I have written this code in js, but I need to rewrite it in ejs because it can't be seen by the user after the page is loaded. This is my code:
<script type="text/javascript" src="js/showads.js" class="deleteMe"></script>
<script type="text/javascript" class="deleteMe">
if(window.canRunAds == undefined){
window.location = "/welcome";
}
$('.deleteMe').remove();
</script>
I have this file named showads.js that contains a canRunAds variable. If the client has adblock enabled this file won't be imported, making the canRunAds variable undefined, and if is the client will be redirected to '/welcome', and then I just delete those 2 scripts, but it doesn't work, because the client can see it and maybe bypass it. Is there a way to write this in ejs, because when I tried it, I got an error saying window is undefined. Thank you!
It's true that you can run ejs in the client side without any server ( node.js ) but you can't access the DOM with it ( like you're doing now with JQuery ), so i assume all what you can parse to EJS
is :
<%
if(window.canRunAds == undefined){
window.location = "/welcome";
}
%>
JavaScript on the server doesn't have a window object. What can be done however is check that the window object is available at runtime, and conditionally run your code if it's accessible:
<script type="text/javascript" src="js/showads.js" class="deleteMe"></script>
<script type="text/javascript" class="deleteMe">
// Check if window exists, and that canRunAds doesn't
// On the server, the code within this block should never run
if(window && !window.canRunAds){
window.location = "/welcome";
}
// Bonus points using the same principle: Avoid assuming jQuery is available in
// inline script blocks.
if(window && window.jQuery) {
$('.deleteMe').remove();
}
</script>
Note that if your showads.js script is being run on the server, you'd also have to wrap any call to window in an if() check, otherwise the server will continue to throw an error.
I am building a web app in which I have a number of clickable maps, stored as static SVG files, that I would like to be able to swap dynamically based on a menu-click. So far, I have javascript code to call my Catalyst controller, and I would like it to return the contents of the SVG file in the response body. So far I can get the javascript to catch the menu clicks and call the controller, and in the controller I am able to get the name of the file out of my database. I am stuck at that step, though, and have been thus far unable to find out how to read the contents of that file in the controller and return it to the javascript controller. Any help would be appreciated!
UPDATE:
The (Edited) code below works, but I'm not sure if this is the best way. I would definitely be open to suggestions on ways to improve my process. Thanks!
Javascript:
$(document).on("click",".map_select", function(e){
$(document.getElementById("som_map")).load("[% c.uri_for('/maps/update_map/') %]" + this.title);
})
HTML
<svg id="som_map" class="mapmain" width="720px" height="430px">
</svg>
PERL
sub update_map :Path :Local :Args(1) {
my ( $self, $c, $map_id ) = #_;
my $fields = $c->model('DB::Map')->find($map_id);
my $map_file = $fields->get_column('map_file');
my $svg;
my $path = "root/static/svg/$map_file";
open my $fh, '<', $path;
{
local $/ = undef;
$svg = <$fh>;
}
close $fh;
$c->res->body($svg);
}
SVG files are stored in root/static/svg/
Unless you have a reason to do it, I would use your web server (Apache, nginx, ...) serve the file for you instead of handling the file I/O inside of your controller.
In your load function in javascript pass in a function that returns a URL for you:
$(document.getElementById("som_map")).load(getSVGUrl(this.title));
Then define that function to call Catalyst to get the appropriate URL for the given mapId:
function getUrl(mapId) {
var returnUrl;
jQuery.ajax({
url: "[% c.uri_for('/maps/update_map/') %]"
+ mapId,
success: function(result) {
if(result.isOk == false)
returnUrl = result.message;
},
async: false,
dataType: 'text/plain'
});
return returnUrl;
}
This function should call your application and just expect to get the URL back. It should be fast enough that making it synchronous does not matter.
Finally, your Catalyst function should just return the URL to the document:
sub update_map :Path :Local :Args(1) {
my ( $self, $c, $map_id ) = #_;
my $fields = $c->model('DB::Map')->find($map_id);
my $map_file = $fields->get_column('map_file');
$c->res->body("<appropriate URL path to document>/$map_file");
}
This will get your application out of the document handling business, trim down your controller, and allow your web server to do what it does best - serve documents.
How can we remove this script injector system and clear functions from memory?
Briefing) Recently the malfeasants at Bigcommerce created an analytics injector (JS) under guise of "monitoring" that is locked in a global variable. They have pushed it to all their 50,000 front facing stores without consent from any OP's. This puts in 2 JS libraries and sets up (plain code) triggers for them to track customer, behavior, and store plans throwing data to their shared 3rd party analytics bay. The issue is that although they run the code, they do not own rights to put in 3rd party libraries like this across thousands of domains out of their realm. Does anyone have ideas on how we can kill this + remove from memory? Is this even legal for them to do?
1) The injector is found in the shared global %%GLOBAL_AdditionalScriptTags%% in the HTMLhead.html panel, which means it non-accessible. The AdditionalScriptTags is also dynamic, meaning it loads different JS helpers based on what page is being requested. Removing the variable is a no-go for that reason.
2) The injector uses various DSL variables PHP side to build out its settings. Here is what it looks like in <head> as I browse logged into our store as a customer. This is putting 2 lines for 2 separate libraries which I will define below (note certain tokens hidden as 1234)
(function(){
window.analytics||(window.analytics=[]),window.analytics.methods=["debug","identify","track","trackLink","trackForm","trackClick","trackSubmit","page","pageview","ab","alias","ready","group","on","once","off","initialize"],window.analytics.factory=function(a){return function(){var b=Array.prototype.slice.call(arguments);return b.unshift(a),window.analytics.push(b),window.analytics}};for(var i=0;i<window.analytics.methods.length;i++){var method=window.analytics.methods[i];window.analytics[method]=window.analytics.factory(method)}window.analytics.load=function(){var a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src="http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/analytics.min.js";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)},window.analytics.SNIPPET_VERSION="2.0.8",window.analytics.load();
// uncomment the following line to turn analytics.js debugging on
// shows verbose events and other useful information
// analytics.debug();
var storeId = '123456',
userId = '921';
// initialize with Fornax and Segment.io
var providers = {
Fornax: {
host: 'https://analytics.bigcommerce.com',
cdn: 'http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/fornax.min.js',
defaultEventProperties: {
storeId: storeId
}
},
'Segment.io': {
apiKey: '1sbkkbifdq'
}
};
var fornaxEnabled = false;
var segmentIOEnabled = false;
var isStorefront = true;
if (!fornaxEnabled) {
delete providers.Fornax;
}
if (!segmentIOEnabled || isStorefront) {
delete providers['Segment.io'];
}
analytics.initialize(providers);
// identify this user
analytics.identify(
userId || null,
{"name":"Test Dude","email":"test#test.com","storeHash":"123456","storeId":123456,"namespace":"bc.customers","storeCountry":"United States","experiments":{"shopping.checkout.cart_to_paid":"legacy_ui","search.storefront.backend":"mysql"},"storefront_session_id":"6b546880d5c34eec4194b5825145ad60d312bdfe"}
);
})();
3) The output libraries are found as 2 references in the <head> and as you see if you own/demo a BC store, are rather un-touchable:
<script type="text/javascript" async="" src="http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/fornax.min.js"></script>
<script type="text/javascript" async="" src="http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/analytics.min.js"></script>
How can we break the injector and these trackers and prevent them from loading? Is there a way to remove their functions from memory? Speaking on behalf of many thousands of OP's and segment.io here, we are all at our wits end with this.
I've been hacking away at this too and I found something that works well to disable most/all of it.
Before this line:
%%GLOBAL_AdditionalScriptTags%%
Use this code:
<script type="text/javascript">
window.bcanalytics = function () {};
</script>
So you will end up with something like this:
%%GLOBAL_AdditionalScriptTags%%
<script type="text/javascript">
window.bcanalytics = function () {};
</script>
The <script> tags from part 3 of your question will still load as those are always PREpended before the first non-commented out <script> tag, but most, if not all, the analytics functionality will break, including external calls, and even fornax.js won't load. Hope this helps.
Per the question I linked, for you case to at least remove the scripts from Step 3 this is what you should do :
var xhr = new XMLHttpRequest,
content,
doc,
scripts;
xhr.open( "GET", document.URL, false );
xhr.send(null);
content = xhr.responseText;
doc = document.implementation.createHTMLDocument(""+(document.title || ""));
doc.open();
doc.write(content);
doc.close();
scripts = doc.getElementsByTagName("script");
//Modify scripts as you please
[].forEach.call( scripts, function( script ) {
if(script.getAttribute("src") == "http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/fornax.min.js"
|| script.getAttribute("src") == "http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/analytics.min.js") {
script.removeAttribute("src");
}
});
//Doing this will activate all the modified scripts and the "old page" will be gone as the document is replaced
document.replaceChild( document.importNode(doc.documentElement, true), document.documentElement);
You must make sure that this is the first thing to run, otherwise the other scripts can and will be executed.
I'm really new to web programming. I'm trying to make a form post and get the callback.
I'm trying to use this plugin here: http://malsup.com/jquery/form/#ajaxSubmit
But when I call the: $("#my_form").ajaxSubmit(options); Nothing happens..
What I have done so far:
I have this form
<form method="post" id="my_form" action="record.php" enctype="multipart/form-data" >
// stuff inside..
<input type="button" id = "recordDatabase" value="Rcord on Database" />
</form>
And I have this script:
<script src="http://malsup.github.com/jquery.form.js"></script>
$(document).ready(function()
{
var options =
{
beforeSubmit: showRequest, // pre-submit callback
success: showResponse // post-submit callback
};
$("#recordDatabase").click(function()
{
alert('About to submit: \n\n');
$("#my_form").ajaxSubmit();
alert('submited: \n\n');
return false;
});
});
Finally my two functions are:
function showRequest(formData, jqForm, options)
{
// formData is an array; here we use $.param to convert it to a string to display it
var queryString = $.param(formData);
alert('About to submit: \n\n' + queryString);
return true;
}
function showResponse(responseText, statusText, xhr, $form)
{
alert('status: ' + statusText + '\n\nresponseText: \n' + responseText +
'\n\nThe output div should have already been updated with the responseText.');
}
I´m doing exactly like the example on the site(http://malsup.com/jquery/form/#ajaxSubmit), but it doesn´t work.
Any idea what's wrong?
I don't think you can hotlink to the jQuery plugin on Git. Try downloading the plugin and saving it as a JS file in your application web root.
It looks like you are not referencing your scripts correctly. According to your comment, you have included your scripts like this:
<script src="ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="localhost/js/jqueryPlugin.js"></script>
These are relative URLs. The browser will request the resources from your site by tacking on those relative URLs to the end of the current directory.
Suppose this page is at http://localhost/myapp/mypage.html. The browser will look for your script files at:
http://localhost/myapp/ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
http://localhost/myapp/localhost/js/jqueryPlugin.js
These URLs probably don't exist. Maybe your browser is smart enough to recognise "ajax.googleapis.com" as a domain name and request the data from the domain, but it's less likely that it will recognize "localhost" as a domain.
Add // to the beginning of the URL. This is a "Schema-relative URL" and will use either http or https depending on what the current page is using. We use these kind of URLs to avoid security prompts warning users that some of the content on the page is not secure. Your scripts would then look like this:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//localhost/js/jqueryPlugin.js"></script>