After this weekend my Wicket application cannot correctly detect javascript anymore. It doesn't work on my webhoster, on my local machine and I tested it also on another computer.
My detection script:
WebClientInfo clientInfo = (WebClientInfo)WebSession.get().getClientInfo();
if(!clientInfo.getProperties().isJavaEnabled()){
System.out.println("not enabled!");
WebSession.get().setClientInfo(null);
}
plus this in the application class:
getRequestCycleSettings().setGatherExtendedBrowserInfo(true);
I also created a wicket app from scratch, same result, no javascript detection.
While writing this I checked it in the Internet Explorer. Works fine with IE 8 + 9. Doesn't work with FF 11.0. Wicket version is 1.5.5.
Anyone can confirm this behavior? (possible JIRA-worthy...)
UPDATE: I found the cause of this behavior. isJavaEnabled checks if Java (not Javascript) is enabled. Firefox (silently) blocked the Java plugin on April 2nd, therefore no javaEnabled property set: https://addons.mozilla.org/en-US/firefox/blocked/p80. Cumbersome.
Likely this never worked, and the fact that it seemed to was dumb luck.
Looking at the javadocs for ClientProperties.isJavaEnabled(), it returns the client's navigator.javaEnabled property, which reflects whether Java is enabled, not JavaScript.
Java != JavaScript.
An alternative is to use the 'user agent' string:
public boolean javascriptSupported() {
WebRequest webRequest = (WebRequest) getRequest();
String userAgent = webRequest.getHeader("User-Agent");
if (userAgent == null || userAgent.startsWith("Googlebot")) {
return false;
}
return true;
}
I have used this to fallback on AjaxLazyLoadPanel for search engines, although you would need to expand on the list of user-agents above.
There is also WebRequest.isAjax(), which might be useful too, as it is used to determine the RedirectPolicy used, and thus, the behaviour of Wicket when Javascript is not present.
Related
We have a SPA application which should be shown in SAP HtmlViewer Component (http://help.sap.com/erp2005_ehp_04/helpdata/en/c9/147a36c70d2354e10000009b38f839/content.htm).
According to docs the component should use the system browser, which is IE10 or on some stations IE11.
The problem is that the javascript engine behaves like the one in IE8. There are missing functions such as Array.isArray, addEventListener, Object.isExtensible etc., which leads me to believe that the brwser engine is IE8. However, when we check the user agent string it says IE10/Trident6.0, which is IE10. I am using this code to test javascript:
alert('test string.trim ' + str.trim);
alert('test Array.map ' + arr.map);
alert('test Object.isExtensible ' + Object.isExtensible );
alert('test Object.defineProperty ' + Object.defineProperty );
, and the first three are undefined.
Also, jQuery 2+ does not work (addEventListener undefiend, isArray undefined etc.), but jQuery 1 does work.
I have tried to include X-UA-Compatibility meta tag and http headers with IE=EDGE to force behavior of the newest browser (though I thing it just change document rendering and not the javascript features), but to no avail.
I also checked the registry [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION] on the computer where the SAP client is running and there is set SAPLOGON.EXE set to 0x02710 (which is IE10 according to https://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx).
The questions are:
are there any properties in windows system to force web browser components (which uses the system browser) to use old implementation of javascript or disallow some of the methods?
particularly in SAP, is it possible to force HtmlViewer component to behave in terms of javascript differently?
or more generally, does have anybody idea why this could be happening?
Any help will be be appreciated.
This has been driving me crazy. I'm trying to migrate some legacy applications to a new server and I'm having a lot of problems with document.all being peppered throughout the code.
Before you say it, I know. Don't use document.all. It's there and there's nothing I can do about it...this particular problem has JavaScript within an assembly for which I do not have the source code and I don't have permission to redevelop.
My main confusion is that the current version of the application is working when I test in the same browser as my migrated version. It's a straight copy and paste job and no code has changed during the migration, but when I run the app on the new server document.all(element) always returns null.
Does IIS or newer .NET frameworks somehow handle client-side scripts differently?
I'm coming from .NET 2.0 hosted on Windows Server 2005 with IIS 6, and going to .NET 4.0 hosted on Windows Server 2012 with IIS 8.
I'm looking for ANY idea why these would be behaving differently when tested in the same browser
UPDATE:
A user control being targeted by document.all is getting encoded which is messing up the ID of the control, i.e. what should be 'elementId' is being outputted as 'elementId'
The code in the assembly is using Attributes.Add which is including single quotes. I've found a number sources suggesting a new class such as:
public class HtmlAttributeEncodingNot : System.Web.Util.HttpEncoder
{
protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
{
output.Write(value);
}
}
being added which will allow encoding to be turned off by using <httpRuntime encoderType="HtmlAttributeEncodingNot"/> in the web.config, but I am not able to add new classes to this project
I'm going to leave the accepted answer as it is, but add this answer in case anyone else has issues with this in the future.
My circumstances changed and I was able to add a class to the project. The class in my question:
public class HtmlAttributeEncodingNot : System.Web.Util.HttpEncoder
{
protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
{
output.Write(value);
}
}
along with using the class for the encoding in the web.config:
<httpRuntime encoderType="HtmlAttributeEncodingNot"/>
was sufficient for dealing with the single quotes in Attributes.Add being encoded to $#39;
Additionally, something to look out for with old JavaScript is the way .net renders the ClientID of controls. Using a combination of the above code, along with <xhtmlConformance mode="Legacy"/> , and clientIDMode="AutoID", I was able to render the html the same as it's 2.0 equivalent and solve my problem for the time being.
It sounds like your project is ending it's life and you just want to breath new life in to it. I think document.all is done as of IE11, isn't it - so the clock is ticking.
What I'd suggest is writing some Javascript to iterate the DOM and look for any encoded IDs - then change those back to the .NET 2 form. Run that JS at the bottom of the page (as opposed to onload) and hopefully nothing will have tried to access document.all before you 'correct' the ids.
I am looking for a way to determine
a) whether or not a user has a specific ActiveX control installed, and
b) what the version of that control is in either Javascript or Silverlight.
I have used the following javascript code to determine the existence of the control:
var activex;
try {
activex = new ActiveXObject('SomeProgId');
} catch(e) {
activex = null;
}
if (activex) {
alert("found");
} else {
alert("not found");
}
And that seems to work just fine.
But I see no way to access any version properties (or any properties at all) from that activex object.
I need to know what version the user has in order to determine if they need to be redirected to install a new version?
Any thought on the same are appreciated.
As far as I know, there's no way to get the version information unless it's exposed as a property on the object's interface.
Having said that, you can solve this problem by including a version specifier after the #version= in the OBJECT tag's CODEBASE attribute. The object tag will prompt the user to upgrade the control if the version test isn't met.
See http://msdn.microsoft.com/en-us/library/941zhks9(v=vs.80).aspx for more details.
I want to identify if the broswer is IE then goto if block, other browser to else block in Java script.
I have one code here,
var browserName=navigator.appName;
if(browserName == "Microsoft Internet Explorer"){
IE code
}
else{
Other code
}
but i want to know is there any other way of implementing it?
Rather than do browser sniffing, you should do feature detection. Later versions of IE may support standards compliant stuff that in older versions you needed to work around or use MS-specific stuff.
Microsoft themselves have written up about the best way to do this and provide examples of both bad code (via sniffing) and good code (via detection). Make sure you go down the "good code" route.
I just started using this script to identify browser, version, and OS:
http://www.quirksmode.org/js/detect.html
If you are needing to use different code based on browser support for certain objects or methods, it's usually better to use object or method detection instead of browser detection. I use the browser detection for collecting statistics on my users, not for enabling or disabling features.
Quirksmode has a short article about why you don't use browser detection this way: http://www.quirksmode.org/js/support.html It's also linked from the browser detection script.
I found that This task is quite difficult as browsers all have similar names and different userAgent strings, so this is my Conditional statement to identify browsers.
I used this to identify the browser for different style sheets.
function styc()
{
var str = navigator.userAgent;
var res = navigator.userAgent.match(/Trident/);
var res2 = navigator.userAgent.match(/Firefox/);
if(res=="Trident"||res2=="Firefox")
{
//alert(navigator.userAgent);//for testing
document.getElementById('IE_fix').setAttribute("href", "IE_fix.css");
}
else
{
//alert("no");//for testing
document.getElementById('IE_fix').setAttribute("href", "mt_default.css");
}
}
Find a unique word in the userAgent string match it and check if the condition is true or not true depending on what you are doing.
The unique word I found for IE is Trident, and also identifies IE versions according to MicroSoft(not positive on this).
I am interested if which would be the best place to detect the client's user-agent, client-side (javascript) or server-side? I brought up the question due to the fact that some IE8 users are getting a message saying they're using IE6.
The short and correct answer is : do not use anything that relies on UserAgent sniffing.
To reliable be able to adjust code paths you should test for the specific 'thing' that the codepath is adjusted for, primarily features. This is called Feature Detection.
So if feature X is supported we do this, if not we do that.
Deducing if a feature is supported based on which UserAgent is present will rapidly fail, especially when new browsers come to the marked.
Take the following example, which can actually be found in several major libraries (!)
if (isIE8) {
// use new feature provided by IE8
} else if (isIE7) {
// use not so new feature provided by IE7 (and IE8)
} else {
// use fallback for all others (which also works in IE7 and IE8)
}
What do you think happens when IE9 comes along?
The correct pattern in this case would be
if ("addEventListener" in foo) {
// use DOM level 2 addEventListener to attach events
foo.addEventListener(...
} else if ("attachEvent" in foo) {
// use IE's proprietary attachEvent method
foo.attachEvent(...
} else {
// fall back to DOM 0
foo["on" + eventName] = ....
}
The User-agent available on both sides should be the same, unless there's funny stuff going on, which normally isn't.
If you want to show a message to IE6 users, I suggest you use conditional comments. They're an IE-specific feature and work very well for detecting IE versions.
The information found through client or server-side detection is basically the same.
Keep in mind it is extremely easy to spoof what browser you're in. There is no fail-safe way to detect all browser types accurately.
i don't know how you're checking for the user agent, but i'd do this way:
<%=
case request.env['HTTP_USER_AGENT']
when /Safari/
"it's a Mac!"
when /iPhone/
"it's a iPhone"
else
"i don't know :("
end
%>
checking directly in the user request seems to be the most consistent way to verify the user browser. And the request.env is avaliable in your controller and views, so you could pass this to rjs if needed.
For those who need to get the actual user-agent using JavaScript, you can use navigator.userAgent