I have a .NET MVC5 application using C#, HTML and Javascript.
I need to know the link of the host so I can send a specific file in a specific folder to the user.
In my local computer, when I test and develop the application, the path the app uses is the following:
localhost:1234/Home/Scripts/myScript.js
However, in the real deployment server, the path changes:
www.superhost.com/Apps/MyApp/Home/Scripts/myScript.js
I am trying to send this file to the user with the following JQuery, when a button is clicked:
$("a.btn.btn-default").click(function () {
download("/Scripts/myScript.js"); //download is a personal function, unimportant
return false; //prevent browser defualt behavior
});
The problem is that when I click the button, I get in the consolo an erorr - 404 error, which means the server is not finding the file.
In fact the server is searching for the file on the path "/Scripts/myScript.js", but the file is in "Apps/MyApp/Home/Scripts/myScript.js".
How do I make my javascript smart enough to figure the correct path?
One solution I use a lot is to inject a site-root URL into the page using something like this:
<body data-root="#Url.Content("~/")">
Which converts to the actual website base URL at runtime.
You then use that injected value, from all jQuery code, using:
var root = $('body').data("root");
You can simply prepend that to any relative URLs to make them work correctly:
$("a.btn.btn-default").click(function () {
download(root + "Scripts/myScript.js"); //download is a personal function, unimportant
return false; //prevent browser defualt behavior
});
Note: this approach will work in cases where the routing changes:
e.g / vs /home/index/ vs /home/ which are all the same page, but different URLs
Remove the leading / from your download path.
You actually don't need an absolute path (and to know server's home folder) to access a file, target it relatively from the page you invoke the download from.
note: If you are using page relative paths, you must make sure you don't move the page the download script is executed from.
I always use in my layout the next code:
<script type="text/javascript">
var rootUrl = "#Url.Content("~/")";
</script>
And when I need it, i use for example:
$("a.btn.btn-default").click(function () {
download(rootUrl + "Scripts/myScript.js"); //download is a personal function, unimportant
return false; //prevent browser defualt behavior
});
Related
I created a login page with javascript. After a succesful the function loadMainActivity is called. As of now the contents are as follows:
async function loadMainActivity(){
document.getElementById("container").innerHTML = "This is a text.";
}
It works. However, now I want to load a complete HTML page upon a succesful login. I tried several plugins to this end. However, all of them require me to load a file. As I see it I have two options:
Provide an extra file with the app. This would enable my users to see the source, which I don't want.
Host the file on a server. This would require my users to have an active internet connection when using the app, which I also don't want, for now at least.
I thought about "stringifying" the HTML page and replacing "This is a text." with the obtained HTML string. That way I could keep the source closed. But this seems like a lot of extra steps. Besides, I cannot find a good method to do this stringification of HTML text.
How to solve this problem for a Cordova app?
I found that this can be done with the jQuery library, nothing specific to Cordova:
async function loadMainActivity(){
$.get("mainactivity.html", function( my_var ) {
document.getElementById("container").innerHTML = my_var;
});
}
I'm a tester and I'm going to test a page index.htm. I'm not allowed to change the target.
To test the page, I need to change some production code to mock code. So I think what I can do is to inject my mock code in a separate js file into the page. The mock code in mock.js looks like as below:
ProductionFunc.prototype.load = function()
{ // return fake data object}
ProductionFunc.prototype.save = function()
{ // fake save }
As a result, the BODY of index.htm in the browser should contain one line like <script src="mock.js"></script>
So the problem is how can I inject my mock code into the page without modifying the physical disk file index.htm.
There are about 100 test cases so 100 different mock js files are created respectively. I also created a loader.htm with 100 buttons on it. When a button is clicked, a new index.htm (injected with one mock js) opens. I wonder if the file name can be parameterized or not.
I know it can be done by some server side technology, such as ASP.NET. But I wonder if it can be done with pure Javascript without having to start a server process.
I have an HTML page that has a reference to some scripts like these ones:
<script charset="utf-8" src="Content/Styles/ThemeForest/assets/js/vendors.js"></script>
<script charset="utf-8" src="Content/Styles/ThemeForest/assets/js/app.js"></script>
The problem is, that when I upload my site to a server, it is no longer working.
I figured that if I instead add the web application name, it will work again. Something like this:
<script charset="utf-8" src="MySite/Content/Styles/ThemeForest/assets/js/vendors.js"></script>
<script charset="utf-8" src="MySite/CContent/Styles/ThemeForest/assets/js/app.js"></script>
Now, the thing is, that I may not know how the web application name would be like once it is uploaded to a server... so, I would like to dynamically add the application name to the src.
I noticed that there is a JavaScript function called window.location.pathname, which can bring me the web application name (if any). I could concatenate this to the rest of the route and it should work.
Now, the catch is, this is all on a regular HTML page.
Is there a way that I can set a custom route to those script tags using basic JavaScript functions? Or any other ideas?
You can use something like $script, just add that lines of code in your app.run or any other place, and call it with an array of the routes of the js files that you want to load. You said that you could get the web application name, so just pass the name of the app concatenated with the path of the script:
var dependenciesLoadingFactory = function(deps) {
return ['$q', '$rootScope', function($q, $rootScope) {
var deferred = $q.defer();
$script(deps, function() {
$rootScope.$apply(function() { deferred.resolve(); });
});
return deferred.promise;
}];
};
If you link to a source document starting with a directory or the filename itself (like you did in your question), the lookup will look for it starting in the same folder that your current file (this would be the html file that holds your script tags) is in.
You could also link to files in parent directories relative to your current location, like this:
../file.js
You can alternatively link to a path starting with a slash:
/dir/to/your/file.js
This will start looking in the root directory of your page, meaning the directory your domain or subdomain points to. You can't successfully link to files that are above your root directory.
Finally, if your files are on another server, make sure you include the full path including the http:// snippet:
http://example.website.com/dir/file.js
Under normal circumstances, there should really be no reason to deviate from these methods, but if you absolutely have to dynamically set a directory, I suggest you use php because it's server-side and therefore faster for the user, and available if they have javascript disabled (which is important if you link to other files such as style sheets in this way):
<?php $directory = '/dir/'; ?>
<script src="<?php print $directory; ?>file.js"></script>
Of course for this to work, your server has to have php running.
I have the following function that activates when I click on some links:
function showPage(page) {
var History = window.History;
History.pushState(null,null,page);
$("#post-content").load(page + ".php");
}
The content of the page updates, the URL changes. However I know I'm surely doing something wrong. For example when I refresh the page, it gives me the Page Not Found error, plus the link of the new page can't be shared, just because of the same reason.
Is there any way to resolve this?
It sounds like you're not routing your dynamic URLs to your main app. Unless page refers to a physical file on your server, you need to be doing some URL rewriting server-side if you want those URLs to work for anything other than simply being placeholders in your browser history. If you don't want to mess with the server side, you'll need to use another strategy, like hacking the URL with hashes. That way the server is still always serving your main app page, and then the app page reads the URL add-on stuff to decide what needs to be rendered dynamically.
You need to stop depending on JavaScript to build the pages.
The server has to be able to construct them itself.
You can then progressively enhance with JavaScript (pushState + Ajax) to transform the previous page into the destination page without reloading all the shared content.
Your problem is that you've done the "enhance" bit before building the foundations.
I have a bizarre routing issue with my ASP.NET MVC project that I hope you guys can help me with.
Overall everything works fine when I run the project off my localhost or run it on the server while it's deployed directly at http://myServerName. The problems start when I deploy the application to various enviornments on the server located under different virtual directories. For example: http://myServerName/QaEnviornment or http://myServerName/TestEnviornment
The problem is that all Javascript calls to application URLs ignore my environment virtual directories and fail.
For example on my QA server whenever I have to make an Ajax call I take a standard approach such as:
var myUrl = '/ControllerName/ActionMethodName/'
$.ajax({url:myUrl,success:function(){Do stuff} })
Because my application is deployed on http://myServerName/QaEnviornment, when rendered I expect myUrl to be http://myServerName/QaEnviornment/ControllerName/ActionMethodName. Instead it comes back as http://myServerName/ControllerName/ActionMethodName and ofcourse fails.
To get around this for now I declared a global Javascript variable that contains the environment folder name and when I build URLs for javascript calls I have to remember to ALWAYS construct them as var myUrl = myGlobalFolderVar + '/ControllerName/ActionMethodName/'
Using a global JavaScript variable to get around this issue seems as a bad solution to me. Is there anything I can do to get routing to work properly so whenever JavaScript calls are made whatever subfolder the application is running under is always included in the URL ?
Instead of always having to remember to construct them correctly, make a helper function that you call to create your URLs
function CreateUrl(string path){
return myGlobalFolderVar + path;
}
To answer your second question, not really. Routing is not aware of what made the request and you cannot always rely on the X-Http-RequestedWith header to base that decision on. In addition, your site application root is not at the domain root, therefore routing would only kick in when it visits your application. The only other way I am aware of is to have MVC actually generate the Url for you (var url = '#Url.RouteUrl(params)';) but this does not help at all when you have your JavaScript in a single or a few .js files.
EDIT
The above function is a JavaScript function that can sit anywhere you would like in your application, including external JS files. As for setting your myGlobalFolderVar, there are a few ways you could set this.
1.Actually hard code the variable in your external JS file.
var myGlobalFolderVar = 'TestEnviornment';
This is hard however if you are deploying to several different testing servers.
2.If you are using web.config transformations, you could add an AppSettings key/value pair in your web.config transformations depending on build type. Then, using that value, set your global Javascript variable in your master page layout/views.
<appSettings xdt:Transform="Replace">
<add key="folderLocation" value="TestEnvironment" />
</appSettings>
In your external JS file
//this makes it a site wide/global variable in any place you
//include your external JS file
var myGlobalFolderVar = '';
And in your master view
<script type="text/javascript">
myGlobalFolderVar = '#ConfigurationManager.AppSettings["folderLocation"]'
</script>
3.Same as number two, but use the URL helpers to figure out what the path to your application is in your master view instead of using the web.config transformations
<script type="text/javascript">
myGlobalFolderVar = '#Url.Content("~/")'
</script>
The basic idea is using .NET to figure out where it lives and set a global JavaScript variable with that path information. Then, in conjunction with the helper JavaScript function provided at the top of this answer, you can correctly generate paths as needed throughout your application - regardless of path depth, deployment location or any other deployment type concerns.
var myUrl = CreateUrl('/ControllerName/ActionMethodName/');
$.ajax({url:myUrl,success:function(){Do stuff} });