We are having an issue with our web application (JSF 1.2 + Ajax4jsf 1.1 ) .We get the following error
**Message: Permission denied
Line: 27
Char: 222
Code: 0
URI: http://uat.example.com/ABC/a4j.res/org.ajax4jsf.framework.ajax.AjaxScript.jsf**
This problem is sporadic and happens 50% of the times.
Happens only on IE8 in all other browsers we do not see this problem.
When this error occurs the whole page blanks out. Howevere a Refresh brings the page back.
We did go through couple of articles regarding IE QUIRK VS standard mode.
Force IE8 Into IE7 Compatiblity Mode
Did not help.
NOTE: This is not cross site scripting issue as the domain where the script (generated by JSF ) is the same domain where our app is installed.
Please let us know if some has solved this issue.
I see a similar problem posted by some one at
http://www.coderanch.com/t/490213/JSF/java/support-IE
Found the fix to the problem.Fixed by modifying ajax4jsf-1.1.0.jar
Root cause: In case of IE-8 the response is being fetched from Ajax object though the response is not read yet. So we added fix for IE by checking the status==200 and readystate=4.
Here is what we did
Open AJAX.js which is under \org\ajax4jsf\framework\ajax\scripts\AJAX.js inside the jar
STEP 1.
Change from:
getResponseText : function(){
return this._request.responseText;
}
TO:
getResponseText : function(){
if (this._request.readyState == 4){
if (this._request.status == 200) {
return this._request.responseText;
}
}
}
STEP 2. Looks for this method and change
FROM:
window.setTimeout(function() {
var isDocOpen=false;
//This functions has few more lines , I have not pasted all code here...
Change TO:
//This is the Fix for IE....The isIE variable is pre defined inside the script.
if (isIE){
if (req.readyState == 4){
if (req.status == 200) {
window.document.open(req.getContentType(),true);
isDocOpen=true;
window.document.write(req.getResponseText());
window.document.close();
}
}
}
else {
//This is the Original code...
//Keep this for all other browsers...
window.document.open(req.getContentType(),true);
isDocOpen=true;
window.document.write(req.getResponseText());
window.document.close();
}
....... Rest of the code should follow as on Original script.
STEP 3:
//COMMENT OUT THIS ORIGINAL CODE. Not sure why this reloading is done for IE
//this was causing IE to send requests...more than once..
//if(isIE){
/ For Ie , scripts on page not activated.
// window.location.reload(false);
//}
Once we made the above change , we used win rar and dropped the Ajax.js file back to ajax4jsf-1.1.0.jar and now IE 8 pains got resolved.
Hope it helps someone out there.
Related
Could anybody help me calling a validation function in can.js?
I'm adding can.jquery.js and can.map.validations.js
and then create such a small example:
var mymap = can.Map.extend({
init: function () {
this.validatePresenceOf('myfield'); // this line reports an error
}
});
when loading page with this script, I get an error in browser:
"Uncaught TypeError: undefined is not a function"
Actually any this.validate* function does not work
After some research I notice that when I put this code under
$(document).ready{}
it works, but if I put it into .js file and load via tag - browser reports an error.
And I'm not going to write all of my js code in the page itself
see here it tells pretty clearly(helped me last time) that you have to use $document.ready() or else it wont work, so try making a new file.js, have $document.ready() contain all your todo-code, and link it up, I hope I am helpful in this regard, if not then bug me up I wont mind at all :) ..
Commenting it late but anyway - it didn't work for me in either case so I just took the sample from http://jsbin.com/jofeq/5/edit?html,js,output - and copied it to my code. Surprisingly it worked after copying - not sure what was wrong on my side.
In that example it looks like this:
var Person = can.Map({
init: function () {
this.validatePresenceOf('firstName');
this.validatePresenceOf('lastName');
}
}, {});
and it works without document.ready tricks or anything else - just included into body tag
I have problem with caching partials in AngularJS.
In my HTML page I have:
<body>
<div ng-view></div>
<body>
where my partials are loaded.
When I change HTML code in my partial, browser still load old data.
Is there any workaround?
For Development you can also deactivate the browser cache - In Chrome Dev Tools on the bottom right click on the gear and tick the option
Disable cache (while DevTools is open)
Update: In Firefox there is the same option in Debugger -> Settings -> Advanced Section (checked for Version 33)
Update 2: Although this option appears in Firefox some report it doesn't work. I suggest using firebug and following hadaytullah answer.
Building on #Valentyn's answer a bit, here's one way to always automatically clear the cache whenever the ng-view content changes:
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
As mentioned in the other answers, here and here, the cache can be cleared by using:
$templateCache.removeAll();
However as suggested by gatoatigrado in the comment, this only appears to work if the html template was served without any cache headers.
So this works for me:
In angular:
app.run(['$templateCache', function ( $templateCache ) {
$templateCache.removeAll(); }]);
You may be adding cache headers in a variety of ways but here are a couple of solutions that work for me.
If using IIS, add this to your web.config:
<location path="scripts/app/views">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</location>
If using Nginx, you can add this to your config:
location ^~ /scripts/app/views/ {
expires -1;
}
Edit
I just realised that the question mentioned dev machine but hopefully this may still help somebody...
If you are talking about cache that is been used for caching of templates without reloading whole page, then you can empty it by something like:
.controller('mainCtrl', function($scope, $templateCache) {
$scope.clearCache = function() {
$templateCache.removeAll();
}
});
And in markup:
<button ng-click='clearCache()'>Clear cache</button>
And press this button to clear cache.
Solution For Firefox (33.1.1) using Firebug (22.0.6)
Tools > Web-Tools > Firebug > Open Firebug.
In the Firebug views go to the "Net" view.
A drop down menu symbol will appear next to "Net" (title of the view).
Select "Disable Browser Cache" from the drop down menu.
This snippet helped me in getting rid of template caching
app.run(function($rootScope, $templateCache) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if (typeof(current) !== 'undefined'){
$templateCache.remove(current.templateUrl);
}
});
});
The details of following snippet can be found on this link:
http://oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs/
I'm posting this just to cover all possibilities since neither of the other solutions worked for me (they threw errors due angular-bootstrap template dependencies, among others).
While you are developing/debugging a specific template, you can ensure it always refreshes by included a timestamp in the path, like this:
$modal.open({
// TODO: Only while dev/debug. Remove later.
templateUrl: 'core/admin/organizations/modal-selector/modal-selector.html?nd=' + Date.now(),
controller : function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
}
});
Note the final ?nd=' + Date.now() in the templateUrl variable.
As others have said, defeating caching completely for dev purposes can be done easily without changing code: use a browser setting or a plugin. Outside of dev, to defeat Angular template caching of route-based templates, remove the template URL from the cache during $routeChangeStart (or $stateChangeStart, for UI Router) as Shayan showed. However, that does NOT affect the caching of templates loaded by ng-include, because those templates are not loaded through the router.
I wanted to be able to hotfix any template, including those loaded by ng-include, in production and have users receive the hotfix in their browser quickly, without having to reload the entire page. I'm also not concerned about defeating HTTP caching for templates. The solution is to intercept every HTTP request that the app makes, ignore those that are not for my app's .html templates, then add a param to the template's URL that changes every minute. Note that the path-checking is specific to the path of your app's templates. To get a different interval, change the math for the param, or remove the % completely to get no caching.
// this defeats Angular's $templateCache on a 1-minute interval
// as a side-effect it also defeats HTTP (browser) caching
angular.module('myApp').config(function($httpProvider, ...) {
$httpProvider.interceptors.push(function() {
return {
'request': function(config) {
config.url = getTimeVersionedUrl(config.url);
return config;
}
};
});
function getTimeVersionedUrl(url) {
// only do for html templates of this app
// NOTE: the path to test for is app dependent!
if (!url || url.indexOf('a/app/') < 0 || url.indexOf('.html') < 0) return url;
// create a URL param that changes every minute
// and add it intelligently to the template's previous url
var param = 'v=' + ~~(Date.now() / 60000) % 10000; // 4 unique digits every minute
if (url.indexOf('?') > 0) {
if (url.indexOf('v=') > 0) return url.replace(/v=[0-9](4)/, param);
return url + '&' + param;
}
return url + '?' + param;
}
If you are using UI router then you can use a decorator and update $templateFactory service and append a query string parameter to templateUrl, and the browser will always load the new template from the server.
function configureTemplateFactory($provide) {
// Set a suffix outside the decorator function
var cacheBust = Date.now().toString();
function templateFactoryDecorator($delegate) {
var fromUrl = angular.bind($delegate, $delegate.fromUrl);
$delegate.fromUrl = function (url, params) {
if (url !== null && angular.isDefined(url) && angular.isString(url)) {
url += (url.indexOf("?") === -1 ? "?" : "&");
url += "v=" + cacheBust;
}
return fromUrl(url, params);
};
return $delegate;
}
$provide.decorator('$templateFactory', ['$delegate', templateFactoryDecorator]);
}
app.config(['$provide', configureTemplateFactory]);
I am sure you can achieve the same result by decorating the "when" method in $routeProvider.
I found that the HTTP interceptor method works pretty nicely, and allows additional flexibility & control. Additionally, you can cache-bust for each production release by using a release hash as the buster variable.
Here is what the dev cachebusting method looks like using Date.
app.factory('cachebustInjector', function(conf) {
var cachebustInjector = {
request: function(config) {
// new timestamp will be appended to each new partial .html request to prevent caching in a dev environment
var buster = new Date().getTime();
if (config.url.indexOf('static/angular_templates') > -1) {
config.url += ['?v=', buster].join('');
}
return config;
}
};
return cachebustInjector;
});
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('cachebustInjector');
}]);
Here is another option in Chrome.
Hit F12 to open developer tools. Then Resources > Cache Storage > Refresh Caches.
I like this option because I don't have to disable cache as in other answers.
There is no solution to prevent browser/proxy caching since you cannot have the control on it.
The other way to force fresh content to your users it to rename the HTML file! Exactly like https://www.npmjs.com/package/grunt-filerev does for assets.
I have protocol (like http) with scheme managed with 3rd party App registered in Mac OS X.
I.e, x-someapp://someaction or something like that.
How can I open this URL with Google Chrome?
By default, Chrome starts searching in Google engine instead launching App and passing URL handling to it...
Safari launches some registered App. And it is right thing.
Firefox and Opera asks what to do... and I can launch App also.
But Chrome... Doesn't ask.
I even tried to write some HTML page with JavaScript inside to send XHttpRequest:
function _httpExecuteCallback()
{
if (httpRequestCallbackFunction != null) {
if (httpRequest.readyState == 4) {
if (httpRequest.status == 200) {
httpRequestCallbackFunction();
httpRequestCallbackFunction = null;
}
}
}
}
function _httpGet(url, callbackFunction)
{
httpRequest = false;
httpRequestCallbackFunction = callbackFunction;
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = _httpExecuteCallback;
httpRequest.open('GET', url, true);
httpRequest.send(null);
}
_httpGet('x-someapp://test',function(){})
No results also...
The current accepted solution has a problem with Chrome for SSL https. Watching the console log, Chrome blocks the request because it thinks the custom url protocol is not secure:
[blocked] The page at reports blah blah ran insecure content from customproto//blah blah
Here is a solution (this took me a few days to research):
<input type='button' value='Test Custom Url' onclick='exec()'>
<script>
function submitRequest(buttonId) {
var d = (window.parent)?window.parent.document:window.document
if (d.getElementById(buttonId) == null || d.getElementById(buttonId) == undefined) return;
if (d.getElementById(buttonId).dispatchEvent) {
var e = d.createEvent("MouseEvents");
e.initEvent("click", true, true);
d.getElementById(buttonId).dispatchEvent(e);
}
else {
d.getElementById(buttonId).click();
}
}
function exec(){
var d = (window.parent)?window.parent.document:window.document
var f = d.getElementById('customUrlLink')
if (f ) {f.parentNode.removeChild(f);}
var a = d.createElement('a');
a.href = 'mycustomproto://arg1';
a.innerHTML = "Link"
a.setAttribute('id', 'customUrlLink');
a.setAttribute("style", "display:none; ");
d.body.appendChild(a);
submitRequest("customUrlLink");
}
</script>
This code will not work for IE. I've found using this technique IE limits the argument of the custom protocol to less than 1000 where as using the iFrame technique IE will allow 2083 chars.
The only way to overcome the url limit in javascript is chuck the data and call multiple times. If anyone wants to take a stab at that, please let me know how it goes. I would like to use it.
To handle long urls in the executing app, pass a token into the app and have it go get the data from a url GET.
So for right now I am using one function for Chrome/FF and another function for IE.
These links helped me develop this solution:
https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page
Simulating a click in jQuery/JavaScript on a link
(wish I had known this a few days ago....hope this helps someone)
==================================================
Update: (8hr later)
==================================================
Jake posted a great solution for chrome: https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page
This works in chrome only:
window.location.assign("customprotocol://");
It will fail in an iframe so this is working:
var w = (window.parent)?window.parent:window
w.location.assign(service + '://' + data)
==================================================
Update: (weeks later)
==================================================
All of the examples of opening the custom protocol, including my own, have a "://" in the url. And this is what is causing the SSL warnings.
Turns out the solution is to change "://" to ":"
so do this:
src="x-myproto:query" .....
and the SSL warnings will go away.
==================================================
Follow: (after months of production use)
==================================================
This has been working well for chorme. Detect the browser and if chrome do this:
var w = (window.parent)?window.parent:window
w.location.assign('myproto://xyzabcdefetc')
For IE and other browsers I do something slightly different.
Note that browsers do impose a limit on how much data you can put in custom url protocol. As long as your string is under 800 chars this seems to be the magic number for which works in all browsers.
It looks like it's Google's locationbar parsing which is getting in the way.
The browser, however, does seem to handle custom URL schemes properly. Try this in your locationbar:
javascript:document.location = 'myscheme://whatever'
Any link on your page that uses the custom scheme should also do the right thing.
I found the solution that works with Chrome.
I use the IFRAME-way.
Example (with JQuery):
$("body").append('<span id="__protoProxy"></span>');
function queryWord(aWord)
{
var protoProxy = document.getElementById('__protoProxy');
if (protoProxy)
{
var word = aWord.replace('"','\"');
protoProxy.innerHTML = '<div style="display:none;"><iframe src="x-myproto://query?' + word + '"></iframe></div>';
}
}
queryWord('hello');
Here's a solution that also includes a redirect to the App Store / Play Store if the user doesn't have the app. It uses a setTimeout for this. It also makes use of an iframe to support more browsers. So this works on Chrome, and any other mobile browser. We use this as my company, Branch. Just modify the two links below to correspond to your URI and App Store link.
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
window.onload = function() {
// Deep link to your app goes here
document.getElementById("l").src = "my_app://somepath";
setTimeout(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8";
}, 500);
};
</script>
<iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
</body>
</html>
Again, this should work on any browser, thanks to the iframe.
If Chrome does not recognize the URL scheme, it defaults to a search.
This is what I see in Safari:
alt text http://img62.imageshack.us/img62/6792/clipboard02oh.jpg
and in Firefox:
alt text http://img138.imageshack.us/img138/9986/clipboard04xk.jpg
I believe the reason why Chrome defaults to search is that there are special google searches that use the colon.
E.g:
define: dictionary
filetype:pdf google chromium
This is one of the annoyances I have with Firefox, I have to jump to the "search box" rather than the address bar to execute these types of searches. Since Chrome does not have a separate search box like Firefox, IE and Safari have, this functionality is required.
Ajax requests won't get you around this.
Some weeks later ....
Looks like window.location.replace('myscheme://whatever') has full cross-browser support , works with chrome,firefox,safari,edge,opera see https://developer.mozilla.org/en-US/docs/Web/API/Location/replace
I have an old site that uses xml documents, and when I created it i had firefox and IE7 to test on, and it worked just great. Since then, IE8 appeared, and it seams that the site does no longer work properly.
This is the current code:
if (window.XMLHttpRequest)
{
XMLHttpRequestObject = new XMLHttpRequest();
XMLHttpRequestObject.overrideMimeType("text/xml");
XMLHttpRequestObject.open("GET", "produse.xml", true);
XMLHttpRequestObject.onreadystatechange = function()
{
if (XMLHttpRequestObject.readyState == 4)
{
xmlDocument = XMLHttpRequestObject.responseXML;
removeWhitespace(xmlDocument);
}
}
XMLHttpRequestObject.send(null);
}
else if (window.ActiveXObject)
{
xmlDocument= new ActiveXObject("Microsoft.XMLDOM");
xmlDocument.async=false;
if (xmlDocument .readyState == 4)
{
xmlDocument.load("produse.xml");
}
}
But I get this error:
Message: Object doesn't support this property or method
Line: 19
Char: 3
Code: 0
which relates to:
XMLHttpRequestObject.overrideMimeType("text/xml");
What should I use instead?
This page shows what the differences are between firefox/ie/ie8 are and has some examples of how to do it:
http://www.javascriptkit.com/jsref/ajax.shtml
Mostly it says that IE8 does not support this method and you have to make sure your server is adding the proper header (text/xml) to the outgoing response.
It also has a link to http://www.javascriptkit.com/dhtmltutors/ajaxgetpost3.shtml that explains the common pitfalls and IE problems.
It says do:
if (mygetrequest.overrideMimeType)
mygetrequest.overrideMimeType('text/xml')
jQuery would be my choice. It is a lot faster and is cross browser supported and on a CDN.
You could strip that code down to just a few lines.
$.get('ajax/test.html', function(data) {
$('.result').html(data);
alert('Load was performed.');
});
I'm writing an extension for firefox. Using dom.location to keep track of visited search results pages, i'm getting this url http://www.google.com/search?hl=en&source=hp&q=hi&aq=f&aqi=&oq=&fp=642c18fb4411ca2e . If you click it, the google search results for "hi" should come up. You'll know that from the title bar - because the rest of the page won't load. This happens with any google search. Oddly enough, if you cut part of it off, so say, http://www.google.com/search?hl=en&source=hp&q=hi - it works! But Googling "hi" myself does give me a longish URL - http://www.google.com/#hl=en&source=hp&q=hi&aq=f&aqi=&oq=&fp=db658cc5049dc510 . I know for a fact that the first time that URL was visited, the page loaded, I did it myself.
Can anyone make reason out of this?
I just tried my experiment again, this time saving the original URL in the location bar. It turns out, dom.location.href is giving a different value. How is this happening?
Original:
http://www.google.com/#hl=en&source=hp&q=hi&aq=f&aqi=&oq=&fp=642c18fb4411ca2e
dom.location.href
http://www.google.com/search?hl=en&source=hp&q=hi&aq=f&aqi=&oq=&fp=642c18fb4411ca2e
window.addEventListener("load", function() { myExtension.init(); }, false);
var myExtension = {
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad, true);
var messagepane = document.getElementById("messagepane"); // mail
if(messagepane)
messagepane.addEventListener("load", function () { myExtension.onPageLoad(); }, true);
},
onPageLoad: function(aEvent) {
var doc = aEvent.originalTarget; // doc is document that triggered "onload" event
// do something with the loaded page.
// doc.location is a Location object (see below for a link).
// You can use it to make your code executed on certain pages only.
var url = doc.location.href;
if (url.match(/(?:p|q)(?:=)([^%]*)/)) {alert("MATCH" + url);resultsPages.push(url);} else {alert(url);
}
}
This snippet comes directly from Mozilla with the matching and alerts my own. I apologize for not posting the code earlier.
Well, on the "right" page http://www.google.com/#hl=en&source=hp&q=hi&aq=f&aqi=&oq=&fp=1&cad=b there seems to be a frame with the "wrong" location: frames[0].location == "http://www.google.com/search?hl=en&source=hp&q=hi&aq=f&aqi=&oq=&fp=1&cad=b". You're probably getting the inner frame's location. I have no idea why, since you didn't post any of your code and just mention some "dom.location", which I never heard of.