I'm using MVC3 and building an a tag (link) using jquery. The problem is I can only get my links to work in either prod or dev, not both. Here is my site's url in production.
http://tvap.mydomain.com
This is my development url.
http://localhost/TVAP
So, I have a link that I'm creating via jquery as follows.
var actionCell = $('#itemlist').find(rowId).find(actionCellId);
$('<a>Edit</a>').attr({ 'id': 'edit-' + response.id, 'href': '/Items/Edit/' + response.id }).appendTo(actionCell);
In production, this works, and creates a link as
<a id="edit-17" href="/Items/Edit/17">
But in development (local) it doesn't work as I need this.
<a id="edit-17" href="/TVAP/ItemManagement/Edit/17">
I get the following from
$(location).attr('host') ==> localhost
$(location).attr('host') ==> http://localhost/TVAP/Items/Index
Either too little, or too much info. I'd know I can check for localhost and append TVAP as needed, but this seems like a hack. Another developer may use the ASP.NET VS dev server and get a URL will contain localhost but without the TVAP as I'm getting.
i.e. - http://localhost:64301/Items/Index
This is what I always do in my _Layout.cshtml:
<head>
<!-- other stuff -->
<script type="text/javascript">
window.myProjectName = {
baseUrl : '#Url.Content("~/")'
};
</script>
<!-- other scripts -->
</head>
Then you can always use stuff like myProjectName.baseUrl+"Controller/Action" for accessing your resources from your own javascript files. This helps you separate the views from the javascript, which is a really good thing.
You don't want to mix markup and javascript - and this is a compromise that goes a long way.
If your JS is directly inside your view (as opposed to an external JS file), you can just use Razor to flush URLs into your Javascript.
// untested
var actionCell = $('#itemlist').find(rowId).find(actionCellId);
$('<a>Edit</a>').attr({
'id': 'edit-' + response.id,
'href': '#Url.Action("Edit")/' + response.id
}).appendTo(actionCell);
Related
I've added a random date param to my CSS and JS files in order to "cache-bust"...
HTML (head)
<!-- STYLE -->
<link href="assets/css/style.css" rel="stylesheet" id="style">
<!-- SCRIPTS -->
<script src="assets/js/scripts.js" id="scripts"></script>
JS (jQuery 3.4.1)
var randomParam = new Date().getTime();
// CSS
var ogCSS = $("head").find("#style").attr("href");
$("head").find("#style").attr("href", ogCSS + "?" + randomParam);
// JS
var ogJS = $("head").find("#scripts").attr("src");
$("head").find("#scripts").attr("src", ogJS + "?" + randomParam);
The CSS file works great. The JS file not so much.
"Network" tab (CSS renamed and called again, JS is not)...
"Sources" tab (JS not called again, has original name)...
I cannot use PHP. I cannot access the server. This is all client-side.
What can I do to make it work? Or is this just how it is?
UPDATE
Forgot to mention that "Elements" in the DevTools show the JS file being renamed properly (see below). It's just not being re-called in "Network" or showing up as being renamed in "Sources". So it's stuck in cache.
I know this question is old, but in case someone comes across it (as I did), the problem is likely here:
ogCSS + "?" + randomParam
That does not create a valid and complete query string. The format of the query string should be:
?<param_name>=<param_value>
but in the code above, we only have ?<param_value>. This means the value will be treated as a name, presumably with a null value, which is generally ignored by most servers I have worked with. To make this correct, you would need to append both a parameter name (often "_" for this use case) and a value, so something like:
ogCSS + "?_=" + randomParam
I'm trying to develop a web application with Thymeleaf and I've created an html page that uses an external JavaScript file to change an image URL.But the standard syntax URL:
document.getElementById("im1").src="images/img1.jpg" ;
does not work.Everything else in the JavaScript code works fine.What kind of URL syntax should I use?Thanks in advance.
Try something like :
<script th:inline="javascript">
/*<![CDATA[*/
var context = [[#{/}]];
/*]]>*/
document.getElementById("im1").src=context + 'images/img1.jpg' ;
</script>
Maybe your code didn't reach the image in the context. Debug or use console to see the URL generated from: context + 'images/img1.jpg'. Then try to acess it via your browser. Normaly it should display the image.
I'd like to inject a couple of local .js files into a webpage. I just mean client side, as in within my browser, I don't need anybody else accessing the page to be able to see it. I just need to take a .js file, and then make it so it's as if that file had been included in the page's html via a <script> tag all along.
It's okay if it takes a second after the page has loaded for the stuff in the local files to be available.
It's okay if I have to be at the computer to do this "by hand" with a console or something.
I've been trying to do this for two days, I've tried Greasemonkey, I've tried manually loading files using a JavaScript console. It amazes me that there isn't (apparently) an established way to do this, it seems like such a simple thing to want to do. I guess simple isn't the same thing as common, though.
If it helps, the reason why I want to do this is to run a chatbot on a JS-based chat client. Some of the bot's code is mixed into the pre-existing chat code -- for that, I have Fiddler intercepting requests to .../chat.js and replacing it with a local file. But I have two .js files which are "independant" of anything on the page itself. There aren't any .js files requested by the page that I can substitute them for, so I can't use Fiddler.
Since your already using a fiddler script, you can do something like this in the OnBeforeResponse(oSession: Session) function
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("MY.TargetSite.com") ) {
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
// Remove any compression or chunking
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
// Find the end of the HEAD script, so you can inject script block there.
var oRegEx = oRegEx = /(<\/head>)/gi
// replace the head-close tag with new-script + head-close
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>console.log('We injected it');</script></head>");
// Set the response body to the changed body string
oSession.utilSetResponseBody(oBody);
}
Working example for www.html5rocks.com :
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("html5rocks") ) { //goto html5rocks.com
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
var oRegEx = oRegEx = /(<\/head>)/gi
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>alert('We injected it')</script></head>");
oSession.utilSetResponseBody(oBody);
}
Note, you have to turn streaming off in fiddler : http://www.fiddler2.com/fiddler/help/streaming.asp and I assume you would need to decode HTTPS : http://www.fiddler2.com/fiddler/help/httpsdecryption.asp
I have been using fiddler script less and less, in favor of fiddler .Net Extensions - http://fiddler2.com/fiddler/dev/IFiddlerExtension.asp
If you are using Chrome then check out dotjs.
It will do exactly what you want!
How about just using jquery's jQuery.getScript() method?
http://api.jquery.com/jQuery.getScript/
save the normal html pages to the file system, add the js files manually by hand, and then use fiddler to intercept those calls so you get your version of the html file
We can modify the document root directory path for PHP using
$_SERVER['DOCUMENT_ROOT'] = "to/some/new/directory";
//Now the "/" which represent the ^(above) path
in .htaccess we have
RewriteBase "/to/some/new/directory"
Now, I need to modify the root directory path to use in javascript. How to do it?
Currently, I am declaring a variable containing static path to the my personalized root directory and using it as
var root = "../to/new/path";
document.location = root+"/somepage.php";
Scenario
I think i should tell a little bit about the scenario, for you guys to catch my idea
Default Web Root Directory
http_docs/
inside it contain a main folder
http_docs/application <-- contains the actual application
http_docs/js <-- contains the script
http_docs/index.html
Now, the application also contains ajax feature for updating, editing, loading new content, or other resources, which if accessed at "/" will represent at /some/path/i/called not /application/some/path/i/called,
To come around this problem
I can define a static variable like
var root = "application/";
and use it somewhere like
$.post(....., function(data) { $(body).append("<img src='"+root+"resources/img1.jpg"); });
But for a single use, defining the path as static, might not be a big deal, but, when the application grows, and certain modification would cause me to change all the paths i give in the js part. I thought, it would be sensible, just like, I do it in PHP, using <img src="/resources/img1.jpg" />
I tried my best to explain this question, if still is not understandable, please community, lets help them understand. I welcome you to edit my question.
EDITED: Trying to answer the updated question
Assuming the JavaScript is called included from the index.html file, if you insert a img tag and use relative urls, they will be relative to the path of the index file. So <img src='application/resources/img1.jpg'> would work just fine. If the script should work for several sublevels (e.g. if the page "application/etc/etc2/somePage.html" needs images from "application/resources/")it may be easier to use absolute urls, and you could include a javascript block on every page generated by php that holds the absolute url to the "root" of the application, like:
<!-- included by php in all html pages, e.g. in defautlHeadter.php -->
<script type="text/javascript">
var rootUrl = "<?= getTheRootUrl() ?>";
</script>
Where getTheRootUrl() is a method or server variable that gives the root url you need. If the url is translated/remapped (by apache etc. outside of what is visible to php) you may need to hardcode the root url in the php method but at least it will be only one file to change if you ever change the root directory.
Then you can use the root url to specify absolute paths anywhere in the application/website using rootUrl + "/some/relative/path" in anywhere in the application.
I once made something like this, to set
window.app_absolute = '<?php echo GetRelativePath(dirname(__FILE__)); ?>'
I also use something like this
static function GetRelativePath($path)
{
$dr = $_SERVER['DOCUMENT_ROOT']; //Probably Apache situated
if (empty($dr)) //Probably IIS situated
{
//Get the document root from the translated path.
$pt = str_replace('\\\\', '/', Server::GetVar('PATH_TRANSLATED',
Server::GetVar('ORIG_PATH_TRANSLATED')));
$dr = substr($pt, 0, -strlen(Server::GetVar('SCRIPT_NAME')));
}
$dr = str_replace('\\\\', '/', $dr);
return substr(str_replace('\\', '/', str_replace('\\\\', '/', $path)), strlen($dr));
}
... Something along those lines, hacked up for demonstration purposes.
Any smart way of doing a "root" based path referencing in JavaScript, just the way we have ~/ in ASP.NET?
Have your page generate a tag with something like:
<link rel="home" id="ApplicationRoot" href="http://www.example.com/appRoot/" />
Then, have a function in JavaScript that extracts the value such as:
function getHome(){
return document.getElementById("ApplicationRoot").href;
}
Use base tag:
<head>
<base href="http://www.example.com/myapp/" />
</head>
...
from now any link use on this page, no matter in javascript or html, will be relative to the base tag, which is "http://www.example.com/myapp/".
You could also use the asp.net feature VirtualPathUtility:
<script>
var basePath = '<%=VirtualPathUtility.ToAbsolutePath("~/")%>';
</script>
Notice: I don't encode the path to a JSON-string (escape quotes, control characters etc). I don't think this is a big deal (quotes for example aren't allowed unescaped in an URL), but one never knows...
I usually create a variable at the top of the js file and assign it the root path. Then I use that variable when referencing a file.
var rootPath = "/";
image.src = rootPath + "images/something.png";
~/ is the application root and not a literal root, it interpets ~/ to mean <YourAppVirtualDir>/
To do a literal root in JavaScript it's just /, i.e "/root.html". There's no way of getting an application level path like that in JavaScript.
You could hack it in the ASPX file and output it in a tag but I would consider the security implications of that.
Kamarey's answer can be improved to support a dynamic base path:
<head>
<base href="http://<%= Request.Url.Authority + Request.ApplicationPath%>/" />
</head>
This will ensure a correct root path regardless of deployment configuration.
To be fair, this doesn't answer the original question, but it elimiates most needs for getting the root path from javascript. Simply use relative URL's everywhere, without prefixing with slash.
Should you still need to access it from javascript, add an id attribute and use document.getElementFromId() as MiffTheFox suggested - but on the base-tag.
Another option that's a bit simpler and more universal would be to take the following:
<script src="/assets/js/bootstrap.min.js"><script>
and use Page.ResolveClientUrl like so:
<script src='<%=ResolveClientUrl("~/assets/js/bootstrap.min.js")%>'></script>
then regardless of what subdirectory the urls will always be rendered correctly.
The following function will calculate the root of the currently running application. I use it to locate the absolute location of resources, when called from somewhere deep within the application tree.
function AppRoot() {
//
// Returns the root of the currently running ASP application.
// in the form: "http://localhost/TRMS40/"
//
// origin: "http://localhost"
// pathname: "/TRMS40/Test/Test%20EMA.aspx"
//
// usage:
// window.open( AppRoot() + "CertPlan_Editor.aspx?ID=" + ID);
//
var z = window.location.pathname.split('/');
return window.location.origin + "/" + z[1] + "/";
}
In the PreRender of your .NET base page, add this:
protected override void
OnPreRender(EventArgs e) {
base.OnPreRender(e);
if (Page.Header != null)
{
//USED TO RESOLVE URL IN JAVASCRIPT
string baseUrl = String.Format("var baseUrl='{0}';\n",
HttpContext.Current.Request.ApplicationPath);
Page.Header.Controls.Add(new LiteralControl(String.Format(Consts.JS_TAG,
baseUrl)));
}
}
Then in your global JavaScript function, add the following:
function resolveUrl(url) {
if (url.indexOf("~/") == 0) {
url = baseUrl + url.substring(2);
}
return url; }
Now you can use it like this:
document.getElementById('someimage').src = resolveUrl('~/images/protest.jpg');
May be a little much for some projects, but works great for full fledged applications.
Solution for ASP.NET MVC applications
This works when using IIS and also IIS Express in VS.
Put this snippet before all scripts load, in order to have the root url variable "approot".
at your service in the scripts:
<script>
var approot = "#Url.Content("~")";
</script>
--> other scripts go here or somewhere later in the page.
Then use it in your script or page script.
Example:
var sound_root_path = approot + "sound/";
var img_root_path = approot + "img/";
the approot variable will be something either:
"/YourWebsiteName/" <-- IIS
or just:
"/" <-- IIS Express
For ASP.net MVC Razor pages, Create a base tag like below in the <Head> tag
<base href="http://#Request.Url.Authority#Request.ApplicationPath" />
and in all your relative javascript URLs, make sure to start without a slash(/) otherwise it will refer from the root.
For ex. create all your urls like
"riskInfo": { url: "Content/images/RiskInfo.png", id: "RI" },
or
$http.POST("Account/GetModelList", this, request, this.bindModelList);
If you want to use it in HTML Still you can use ~, see this
href = #Url.Content("~/controllername/actionName")
See the check box click event in my MVC Application
#Html.CheckBoxFor(m=>Model.IsChecked,
new {#onclick=#Url.Content("~/controller/action("+ #Model.Id + ", 1)"),
#title="Select To Renew" })