Although this question may seem as a duplicate of other questions, it is not.
I have a basic asp.net web application and I simply want to retrieve client time. Here are the problems I encountered:
1- Using C# code DateTime.Now basically gives the dateTime of the place of the server. So obviously it is not useful.
2- Then, I tried to get the datetime from JavaScript (browser time). Past stackoverflow questions suggest that I should use a HiddenField. But it is useful as long as a button ignites a functions which would assign datetime value to a hiddenfield. I tried to assign the datetime value to hiddenfield with window.onload function (so that hiddenvalue can get datetime when the page loads). Another problem occured: according to asp.net page lifecycle, javascript code comes after the page_load event. So another fail.
3- Here is the ultimate solution I came up with:
First, I wrote a JS function that creates a cookie of the offset when called:
function createZoneCookie() {
var zone = new Date().getTimezoneOffset() / -60
var date = new Date();
date.setTime(date.getTime() + (30 * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
document.cookie = "clienttzone=" + zone + expires + "; path=/";
}
Then, I used the following code located in the codebehind(c#):
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Cookies["clienttzone"]==null)
{
ScriptManager.RegisterStartupScript(this,GetType(), "Javascript", "javascript:createZoneCookie(); ", true);
}
}
It works fine, but!! As you know user can access to my js function using the inspect (F12) button in their browser. Thus, they can alter my code and give a false dateTime or even worse create their own arbitrary cookies. And as I was told, it is impossible to make a JS code invisible to the user.
How the hell do people retrieve user timezone without compromising sensitive code?
PLUS Is there a way by which the server side code can use a client-side returning-function? Let me clarify:
ScriptManager.RegisterStartupScript(this,GetType(), "Javascript", "javascript:createZoneCookie(); ", true);
I have used the above code to run a function from the server side but as you know the createZoneCookie function is a void-type function.
My question is: can I get a value from a JS function from the C# side of my code?
this question didn't work because the accepted answer doesn't adress to the question of serverside-clientside value pass.
Related
I have two subdomains foo.example.com and bar.example.com, I am setting javascript cookies on the foo.example.com, but not able access it on bar.example.com, please suggest a way to access the cookie created on the foo.example.com on bar.example.com
In php I set a persistent cookie to do something similar, if it can be accessed from separate browsing sessions it can be accessed cross-domain i'd imagine.
I have "borrowed" this javascript from #pete because I'm not a JS expert, and barely even a novice, but I think something along these lines could work, set a cookie to expire after a year or other time period, as opposed to when browser session closes or the page has been left.
You'll need to do some messing about with it but hey, that's the fun part!
// Build the expiration date string:
var expiration_date = new Date();
var cookie_string = '';
expiration_date.setFullYear(expiration_date.getFullYear() + 1);
// Build the set-cookie string:
cookie_string = "test_cookies=true; path=/; expires=" +
expiration_date.toUTCString();
// Create or update the cookie:
document.cookie = cookie_string;
so what I'm trying to do is pass a simple string variable that contains my error message in C# into my javascript function when I call the function. My function call works fine, but it keeps outputting the wrong thing. This might be important too, I'm calling the Response.Write pieces within my Global.asax.cs file and my javascript file is within my Scripts folder in my MVC project. Based on the research I've found, this is what I currently have after help from the comments:
function KickOutUnwantedUsers(aMesssage) {
console.log("Inside KickOutUnwantedUsers"); //for debugging
console.log(aMesssage); //for debugging
alert(aMessage);
window.open('', '_self').close();
}
It just continues to output this
<%=errorMessage%>
I'm not sure how to fix it, as everything I've found says to pass the variable that way, but I'm wondering if I need to pass it as an actual parameter into the function, and if so, how to do that.
UPDATE: Here is the C# code:
else
{
string user = s.Remove(0, 4);
string errorMessage = "THE FOLLOWING ERRORS MIGHT HAVE OCCURRED: " + user +
" has either been disabled or the account does not exist." +
" PLEASE CONTACT YOUR ADMINISTRATOR. ";
Response.Write("<script type=\"text/javascript\" src=\"Scripts/HelpfulFunctions.js\">");
Response.Write("</script>");
Response.Write("<script type=\"text/javascript\">");
Response.Write("KickOutUnwantedUsers('" + errorMessage + "');");
Response.Write("</script>");
}
SOLVED
#Igor was very helpful in the comments, and I did things as he suggested, which for some reason would not work at first, but then the following day I deletedmy JavaScript file, remade it under the same name and retyped out the javascript code and it worked. Coding is strange sometimes. I must've had a typo or something.
This is what the (badly documented) HttpUtility.JavaScriptStringEncode is for:
// the second argument "true" causes quotation marks to be inserted as well
var message = <%= HttpUtility.JavaScriptStringEncode(errorMessage, true) %>;
First. Such line as
var message = '<%=errorMessage%>';
only makes sense in ASP.NET markup file. In js file it is meaningless, since javascript files are not processed by ASP.NET server-side.
Second. Since you are passing message string as parameter, you need function signature to reflect this:
function KickOutUnwantedUsers(aMessage) {
alert(aMessage);
window.open('', '_self').close();
}
and - note the quotes around the parameter value:
Response.Write("KickOutUnwantedUsers('" + errorMessage + "');");
Let's say i have some textboxes/textareas of which the values have to be stored. The values have to be stored on key press, so that no data is lost when the user closes the page too early. Here's my current code (using cookies):
function createCookie(name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = '; expires=' + date.toGMTString();
} else var expires = '';
document.cookie = name + '=' + value + expires + '; path=/';
}
$('input').keyup(function () {
var $this = $(this);
createCookie($this.attr('name'), $this.val(), 1);
});
jsFiddle
This works great.
With just 4 textboxes i see no problems but imagine having 50+ textboxes or textareas (not accounting usability/user experience). Will this cause any problems?
I'm open to any suggestions/alternatives
I'd opt for using local storage (see http://www.w3schools.com/html/html5_webstorage.asp), seems more scalable than setting a cookie for each text input.
Also, you mention that the values must be set with each keystroke, why not instead keep the value of the current input in memory, and bind a function which commits the value both to the blur event of the input, and also use setTimeout to impose, say, a 1 second delay on saving the value, queuing these timeouts in an array, and clearing outstanding ones on each keyup event, that way you're only writing to the local storage when the user pauses typing, not with every keystroke.
As Jamie suggested local storage is a really good approach, cookies could be used as a fallback if Local Storage is not supported.
On the snippet you have provided you have binded the cookie rewrite process in the keyup event, in order to avoid any data loss.
I have implemented a more neat solution , when the user unloads the window I have tried to serialise the form data and store it.
//save data generic function
function saveData() {
var dataObj = JSON.stringify($("input,textarea").serializeObject());
if (!Modernizr.localstorage) {
saveToLocalStorage(dataObj);
} else {
createCookie("jsonobj", dataObj, 1);
}
}
Modernizr is used to detect when local storage is available. Furthermore , I have found that using separate cookies for each field is an overkill, I have used a single JSON string instead.
Full jsFiddele example: http://jsfiddle.net/ARUM9/5/
Further reading:
Local storage :Storing Objects in HTML5 localStorage
Local storage browser support: http://caniuse.com/#search=localstorage
Using JSON serialisation : Serializing to JSON in jQuery
Modernizr documentation: http://modernizr.com/docs/
Use jquery-storage for saving the values https://github.com/julien-maurel/jQuery-Storage-API/blob/master/README.md
Its really simple
$.localstorage.set(inputfield, value)
For setting
$.localstorage.get(inputfield)
For retrieving.
Cookies are often abused for this purpose but cookies get sent to the server on every request. So storing a ton of data in cookies is not a good idea.
Localstorage however was designed for this purpose and is a simpe key value storw in the browser.
Please note that it is a html5 feature and will not work in some older browsers
To circumvent this you can use the cookiestorage provided by jquery storage. But then you also need to include the extra dependencies mentionend in the readme.md
Then use it like this:
var store = $.localstoreage || $.cookiestorage:
store.set(...........
I have a webapp that sets timezone
post_controller.rb
before_filter :set_time_zone
def set_time_zone
Time.zone = user.time_zone
end
Now, instead of getting the time_zone from the user at registration, I was wondering how I'd set the timezone dynamically from the client side and set it in the before_filter.
I was trying to use detect_timezone_rails gem. The gem provides an easy way to access clientside timezone, simply by calling the function like this from js file.
$(document).ready(function(){
$('#your_input_id').set_timezone();
});
Now, the above code automatically sets your hiddenfield input or select input, but I was wondering if you could simply use the function call to save to session and retrieve it from Rails server. I guess when the user first visits the site, the timezone can be set and the session value can be used to set timezone for the rest of the visit. I'd think it'd be possible to use the session value to set timezone in the before filter. Being pretty new to javascript, I'm not sure how to access Rail's encrypted cookie store to set the value. Is this possible? if so, how can I do this?
thanks in advance,
#javascript
function readCookieValue(cookieName)
{
return (result = new RegExp('(?:^|; )' + encodeURIComponent(cookieName) + '=([^;]*)').exec(document.cookie)) ? decodeURIComponent(result[1]) : null;
}
$(document).ready(function(){
if(readCookieValue("time_zone") === null) {
$.post('/set_time_zone',
{ 'offset_minutes':(-1 * (new Date()).getTimezoneOffset())});
}
#controller:
def set_time_zone
offset_seconds = params[:offset_minutes].to_i * 60
#time_zone = ActiveSupport::TimeZone[offset_seconds]
#time_zone = ActiveSupport::TimeZone["UTC"] unless #time_zone
if #time_zone
cookies[:time_zone] = #time_zone.name if #time_zone
render :text => "success"
else
render :text => "error"
end
end
We did this somewhat differently. We use the gon gem to set a variable on the Rails side if we want to collect the timezone from JS. Then we have JS code on the client that examines that variable, and if set, does an XHR post to an endpoint (like the OP did) with the timezone string as returned by the jstimezonedetect script, which returns an IANA timezone key. Finally, to convert this to a Rails 3.2.19 timezone name, we did ActiveSupport::TimeZone::MAPPING.invert[iana_key]. It took a few steps to figure this out, hope it helps someone.
Is it possible to query AD from javascript?
I'm working from within SharePoint, and I can get the current SharePoint user's information using some js I found on a blog.
But I'm wondering if I can then query AD to see if the current user is in a specific AD group.
I think you'd be better off writing a quick asp.net page that you could call via AJAX and get some JSON back. .NET directory services class are going to be much better at talking to Active Directory than javascript, unless you can find a js library specifically for this (which I haven't been able to find).
This is a little late, but for future visitors from Google, I had to write something in JavaScript to fix a scheduled task that is run with cscript:
var conn = WScript.CreateObject("ADODB.Connection")
var rootDSE = GetObject("LDAP://RootDSE");
var context = rootDSE.Get("defaultNamingContext");
conn.Provider = "ADsDSOObject";
conn.Open("ADs Provider");
var query = "<LDAP://" + context + ">;(&(objectCategory=person)(objectClass=user));samAccountName;subtree";
var cmd = WScript.CreateObject("ADODB.Command");
cmd.ActiveConnection = conn;
cmd.CommandText = query;
cmd.Properties.Item("SearchScope") = 2;
cmd.Properties.Item("Page Size") = 500;
var r = cmd.Execute();
while(!r.EOF)
{
for (var e=new Enumerator(r.Fields);!e.atEnd();e.moveNext())
{
WScript.Stdout.Write(e.Item().name + "=" + e.Item().value + " ");
}
WScript.Stdout.WriteLine("");
r.MoveNext();
}
There is no way known to me how one could access AD from a client script. I could only think of some kind of an ActiveX control which does the job, however that 1) would work only in IE 2) would also be limited to zone settings in IE.
So, the reason is why you need this. Most probably, to be able to show the user something or hide something from the user. If this is the case, you could think of applying the "target audiences" solution to your page (see here - http://office.microsoft.com/en-us/sharepointserver/HA101690531033.aspx). For instance, add two versions of your webpart to the page, one for users who are in the group and another for users who aren't.
If you really need to have this information on the client side in JS, you can create some "AD helper" web service on your server and call into that service using AJAX, as per #squillman's post.