I'm working with an e-learning course that a vendor created (who we no longer deal with) and when I upload the files through my company's security software (HP Fortify Scan) I'm getting multiple errors. I've corrected all the errors expect one. The error is in the dojo.js file and it has to do with a url variable being unvalidated. I'm sure it's a simple fix, but can someone explain what makes this unvalidated? And how can I validate this url variable?
Here is a screen shot of the error message with the code (I put the line number in a comment):
Code:
function xhr(url, options, returnDeferred){
var response = util.parseArgs(
url,
util.deepCreate(defaultOptions, options),
has('native-formdata') && options && options.data && options.data instanceof FormData
);
// THIS IS LINE 11540
url = response.url;
options = response.options;
var remover,
last = function(){
remover && remover();
};
//Make the Deferred object for this xhr request.
var dfd = util.deferred(
response,
cancel,
isValid,
isReady,
handleResponse,
last
);
var _xhr = response.xhr = xhr._create();
if(!_xhr){
// If XHR factory somehow returns nothings,
// cancel the deferred.
dfd.cancel(new RequestError('XHR was not created'));
return returnDeferred ? dfd : dfd.promise;
}
response.getHeader = function(headerName){
return this.xhr.getResponseHeader(headerName);
};
if(addListeners){
remover = addListeners(_xhr, dfd, response);
}
var data = options.data,
async = !options.sync,
method = options.method;
try{
// IE6 won't let you call apply() on the native function.
// THIS IS LINE 11580
_xhr.open(method, url, async, options.user || undefined, options.password || undefined);
if(options.withCredentials){
_xhr.withCredentials = options.withCredentials;
}
var headers = options.headers,
contentType;
if(headers){
for(var hdr in headers){
if(hdr.toLowerCase() === 'content-type'){
contentType = headers[hdr];
}else if(headers[hdr]){
//Only add header if it has a value. This allows for instance, skipping
//insertion of X-Requested-With by specifying empty value.
_xhr.setRequestHeader(hdr, headers[hdr]);
}
}
}
if(contentType && contentType !== false){
_xhr.setRequestHeader('Content-Type', contentType);
}
if(!headers || !('X-Requested-With' in headers)){
_xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
}
if(util.notify){
util.notify.emit('send', response, dfd.promise.cancel);
}
_xhr.send(data);
}catch(e){
dfd.reject(e);
}
watch(dfd);
_xhr = null;
return returnDeferred ? dfd : dfd.promise;
}
Thanks in advance,
Mike
I'd say this is not necessarily an error, it is just that HP Fortify Scan is pointing out a piece of code in dojo/request/xhr.js which may need your attention, in case your server code is not prepared for such an attack... You may validate the url at a higher level code in your application (possibly in your store) where you call the xhr(), not sure if that would satisfy HP Fortify.
Related
Problem: when developing an Ionic2 app, I would like to see the console.log messages generated on my IPhone but I do not have a Mac or I do have one but found that the web inspector feature sucks.
Note this is applicable to any kind of remote javascript, not only to Angular/ionic.
This is a Q&A style question, meaning I'll provide the answer below because I think it's very useful for lots of people.
The solution is a hook into your javascript that will intercept all console.log and errors and send them to a server.
Place the following code into your index.html page:
<script>
// Function that will call your webserver
logToServer = function(consoleMsg) {
// only do this if on device
if (window.cordova) {
let jsonTxt = customStringify(consoleMsg);
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", 'http://yourserver/console2server.php?msg=' + jsonTxt, true); //async
xmlHttp.send(null);
}
}
// Test if you receive this on the server
logToServer("OPENING IONIC APP");
// intercept console logs
(function () {
var oldLog = console.log;
console.log = function (message) {
// DO MESSAGE HERE.
logToServer(message);
oldLog.apply(console, arguments);
};
})();
// intecept errors
if (window && !window.onerror) {
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
logToServer(errorMsg);
logToServer(errorObj);
return false;
}
}
// this is optional, but it avoids 'converting circular structure' errors
customStringify = function (inp) {
return JSON.stringify(inp, function (key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
console.log("circular dep found!!");
return;
}
// Store value in our collection
cache.push(value);
}
return value;
});
}
</script>
On the server side, I use PHP but you could use whatever you want:
<?php
//allow CORS request
header('Access-Control-Allow-Origin: *');
if(isset($_GET['msg'])) {
//you can also log to a file or whatever, I just log to standard logs
error_log("[CONSOLE.LOG] ".json_decode($_GET['msg'], true));
}
?>
Happy debugging!
I have a simple program that is scraping a web site for some items. I am using Angular $http service to call the below C# method to get the markup from the page and then handling everything else with JS. Everything is working perfectly fine with the exception of a minor annoyance: a bunch of 404 errors.
The 404 errors are being displayed in the developer tools once the http get call completes. It's almost like the javascript is trying to interpret the HTML and then fails on all the get requests for the images in the browser:
What I'm trying to figure out is how to get the 404 errors to go away or fail silently (not display in the console). I'm not finding anything in my research but am assuming there is some way to handle this whether it be on the server or client side
C#
public static string GetPageSource()
{
JObject result = new JObject();
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://awebpage.html");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
result["data"] = reader.ReadToEnd();
result["success"] = true;
reader.Close();
response.Close();
}
catch (Exception ex)
{
result["data"] = ex.Message;
result["success"] = false;
}
return JsonConvert.SerializeObject(result);
}
JS
$scope.getPageSource = function () {
var ajaxProcessor = Utils.ajaxMessage('Scraping Beer Menu From Source');
ajaxProcessor.start();
$http({
method: 'POST',
url: 'AJAX/MenuHandler.aspx/GetPageSource',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: {}
}).then(function (response) {
ajaxProcessor.stop();
var result = $.parseJSON(response.data.d);
if (result.success === false) {
Utils.showMessage('error', result.data);
} else {
var beerMenu = new BeerMenu(result.data, $scope.loggedInUser, function (beerMenu) {
$scope.buildDisplayMenu(beerMenu);
});
}
}, function (err) {
ajaxProcessor.stop();
console.log(err);
Utils.showMessage('error', err.data.Message);
});
};
UPDATE
Thanks to #dandavis, my issue is narrowed down to calling $.parseHTML within the buildDisplayMenu function (which calls buildCurrentMenu). Is there anyway to make it ignore the images or any get request?
buildCurrentMenu: function () {
var html = $.parseHTML(this.pageSource);
var menuDiv = $(html).find('.TabbedPanelsContent')[0];
var categories = $(menuDiv).find('h2');
var categegoryItems = [];
var beerArray = [];
for (var i = 0; i < categories.length; i++) {
...
}
return beerArray;
}
The resolution is to remove any img tags (or any other tag that should be ignored) from the page source before calling $.parseHTML
this.pageSource = this.pageSource.replace(/<img[^>]*>/g, "");
I'm trying to script a function which takes all the css/js files marked by attribute-data and refreshes if any of the scripts have been modified on the server side. My initial attempt involved php and jquery/javascript. This new attempt is based on javascript/jquery only!
My problem is that while chaining the ajax requests to these files (for Modification date), all ajax requests stop if file not found. For example, if I rename (existing) style.css to (doesn't exist) style_.css, all the chained ajax requests get aborted, and the code doesn't continue.
var file_url = [url1, url1, url3, url4, url5];
function getLatestModificationDate(file_url){
$.when.apply($, file_url.map(function(url) {
return $.ajax({ type: 'HEAD', url: url, beforeSend: function(jqXHR, settings) { jqXHR.url = settings.url; } });
})).done(function() {
var results = [], lastModified, file_jqXHR;
//each argument passed to this callback for ajax, is of this form [data, statusText, jqXHR]
for (var i = 0; i < arguments.length; i++) {
var obj= {};
file_jqXHR = arguments[i][2]; //jqXHR
lastModified = file_jqXHR.getResponseHeader('Last-Modified');
obj['file'] = file_jqXHR.url;
obj['modDate'] = lastModified;
fileArray.push(obj);
}
mainFunction(fileArray); //the main function, not in scope for this question.
});
}
I tried adding error option in ajax after beforeSend, that didn't allow continuing of remaining ajax requests. Don't know if return ajax apply(.., ..)
could return false to skip the current request for 404, cause I don't know how to skip or return false for the ajax? Is there any quick way to check if the file exists? So that I add only existing files to the file_url array that's passed to the function getLatestModificationDate(file_url){...}
EDIT: Here's a screenshot from the Chrome-Console.
EDIT :
I found this question's answer that uses a new deffered for the ajax complete... could someone provide any simplification on how that code can be used for my question? Thanks!
var myDeferred = $.Deferred();
var origDeferred = $.ajax(...);
// if request is ok, i resolve my deferred
origDeferred.done(function() {
myDeferred.resolve.apply(this, arguments);
});
// if request failed, i also resolve my deferred
origDeferred.fail(function() {
myDeferred.resolve.apply(this, arguments);
});
You can use Try-Catch block:
for (var i = 0; i < arguments.length; i++) {
try{
var obj= {};
file_jqXHR = arguments[i][2]; //jqXHR
lastModified = file_jqXHR.getResponseHeader('Last-Modified');
obj['file'] = file_jqXHR.url;
obj['modDate'] = lastModified;
fileArray.push(obj);
}catch(e){}
}
Been trying to create a basic Ajax library using JavaScript based upon a tutorial in the book "Build your own AJAX Web Applications" by Matthew Eernise (see here) as I want to get more in-depth knowledge of AJAX XML-RPC and REST. Based on the book I have created a JavaScript constructor function to get AJAX or an XMLHttpRequest going, but somehow I seem to suffer from an out-of-scope issue and the Ajax class is not defined in the following script:
function Ajax() {
// properties
this.req = null;
this.url = null;
this.method = 'GET';
this.asynch = true;
this.status = null;
this.statusText = '';
this.postData = null;
this.readyState = null;
this.responseText = null;
this.responseXML = null;
this.handleResp = null;
this.responseFormat = 'text',
// 'text', 'html', 'xml' or 'object'
this.mimeType = null;
} // End Constructor
//Create XMLHttpRequest method with XMLHttpRequest object
this.init = function() {
if (!this.req) {
try {
//Try to create objects for Firefox, Safari, IE7, etc.
this.req = newXMLHttpRequest();
}
catch(e) {
try {
//Try to create object for later versions of IE.
this.req = new ActiveXObject('MSXML2.XMLHTTP');
}
catch(e) {
try {
//Try to create for early versions of IE.
this.req = new ActiveXObject('Microsoft.XMLHTTP');
}
catch(e) {
//Could not create XMLHttpRequest object.
return false;
}
}
}
}
return this.req;
};
//Sending a Request method
this.doReq = function() {
if (!this.init()) {
alert('Could not create XMLHttpRequest object.');
return;
}
//Setting up a request
//open methods with method, url and asycn yes or no
this.req.open(this.method, this.url, this.asynch);
//Make sure mimetype is OK
if (this.mimeType) {
try {
req.overrideMimeType(this.mimeType);
}
catch(e) {
//couldn't override MIME type ... IE6 or Opera?
}
}
var self = this; // fix loss-of-scope in inner function
this.req.onreadystatechange = function() {
var resp = null;
if (self.req.readyState == 4) {
//do stuff to handle response
switch (self.reponseFormat) {
case 'text':
resp = self.req.responseText;
break;
case 'xml':
resp = self.req.responseXML;
break;
case 'object':
resp = req;
break;
}
if (self.req.status >= 200 && self.req.status <= 299) {
self.handleResp(resp);
}
else {
self.handleErr(resp);
}
}
};
this.req.send(this.postData);
};
this.handleErr = function() {
var errorWin;
try {
errorWin = window.open('', 'errorWin');
errorWin.document.body.innerHTML = this.responseText;
}
catch(e) {
alert('An error occured, but this error message cannot be '
+ 'displayed. This is probably because of your browser\'s '
+ 'pop-up blocker. \n'
+ 'Please allow pop-ups from this website if you want to '
+ 'see the full error messages. \n'
+ '\n'
+ 'Status Code: ' + this.req.status + '\n'
+ 'Status description: ' + this.req.statusText);
}
};
this.abort = function() {
if (this.req) {
this.req.onreadystatechange = function() {};
this.req.abort();
this.req = null;
}
};
this.doGet = function (url, hand, format) {
this.url = url;
this.handleResp = hand;
this.responseFormat = format || 'text' ;
this.doReq();
};
The error I get on the page that loads this script with
var hand = function (str) {
alert(str);
}
var Ajax = new Ajax(); // new instance as can ben done with PHP5 constructor classes
ajax.doGet ('/fakeserverpage.php', hand);
and starts up a new instance of Ajax get the error ajax is not defined even though I did add var self = this; // fix loss-of-scope in inner function
to fix the scope issue. What am I missing?
Update 1
Thanks to a tip here Gave new instance a different name so they don't clash:
var hand = function (str) {
alert(str);
}
var ajax = new Ajax(); // new instance as can ben done with PHP5 constructor classes
ajax.doGet ('/fakeserverpage.php', hand);
Now I am a little further. Now I get a new error: Uncaught TypeError: Object #<Ajax> has no method 'doGet'
Update 2
I tried using Ajax.prototype.init instead of this.init as recommended by a co dev here, but I still have the same error..
Update 3
Thanks to #Soufiana Hassou I improved the code by adding Ajax.prototype to all methods. Did not know it was necessary for all to work with the constructor, but it is. Code is here http://pastebin.com/g86k0z8d . I now get this pop-up saying Could not create XMLHttpRequest object. This error message is built into the method so it is working, but it cannot create the object somehow. This means there must be an error in my request for an XMLHttpRequest as I covered all cases and tested this in Firefox 11 for Mac using code on my local MacPorts MAMP. Either that or there is something else I do not know about..
Update 4
Fixed a typo. Then I got a 404 loading the fake server page. Corrected path ajax.doGet ('/ajax/fakeserverpage.php', hand); so now OK. Only I need to get the PHP to generate the code so I get an OK. The header response is OK, but I do not see the AJAX alert yet. Then I checked the console and found this error:
self.req is undefined
http://localhost/ajax/ajax.js
Line 78
See latest code: http://pastebin.com/g86k0z8d . I added some more Ajax.prototype where I thought they were still needed. Now I get:
this.req is null
http://localhost/ajax/ajax.js
Line 100
Update 5
Made some more changes removing some selfs used initially for the out-of-scope issue using var self = this. Code is still the same pastebin, but I have updated it. Now I have:
Ajax.prototype.handleResp is not a function
http://localhost/ajax/ajax.js
Line 92
Update 6
I cleaned up some of the mistakes I made in the req.onreadystatechange = function() function and now I does run. I turned of Firefox pop-up blocker for localhost and on reload it opened another tab and showed the text undefined. So almost there. No errors, just no pop-up with OK. Chrome showed a pop-up with the undefined in the body. Updated code here: http://pastebin.com/g86k0z8d as usual
You are using the same name for your instance and the class itself.
Also, you are declaring Ajax and using ajax, Javascript is case-sensitive.
First, you have var Ajax = new Ajax(); You should have var ajax = new Ajax(); instead.
Secondly, using this outside of the constructor isn't referring to the Ajax object. Try using its prototype instead:
function Ajax() {
// Set properties here
}
Ajax.prototype.init = function() {
// ...
}
See this article on Javascript classes for more information.
I have this code that make 3 requests to a server, the code works fine with the request but when I receive the response the code fails, take avoid the first response and give me the third.
phone.open("POST", '/', true);
phone.setRequestHeader("Content-type", elmnt.getAttribute('ctype'));
phone.send(reqStr);
This is the code that catch the response.
phone = new ConstructorXMLHttpRequest();
onreadystatechange = function(){
if(phone.readyState == 4){
if(phone.status == 200){
var val = phone.responseText;
alert(phone.responseText)
dataInsert(val);
break;
}else{
alert("Problemas status:"+phone.status+" state:"+phone.readyState);
break;
}
}
};
#Hemlock here is the code of the constructor:
function ConstructorXMLHttpRequest()
{
if(window.XMLHttpRequest) /*XMLHttpRequest(Browsers Mozilla, Safari and Opera). */
{
return new XMLHttpRequest();
}
else if(window.ActiveXObject) /*IE*/
{
/*There a several difference between versions of IE, so
* if the kids of MS release a new please put in this Array.*/
var versionesObj = new Array(
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.3.0',
'Msxml2.XMLHTTP',
'Microsoft.XMLHTTP');
for (var i = 0; i < versionesObj.length; i++)
{
try
{
return new ActiveXObject(versionesObj[i]);
}
catch (errorControlado)
{
}
}
}
throw new Error("Couldn't make a XMLHttpRequest");
}
The reason people think this is funny is because your case statement is A) useless because you don't actually want to take different actions depending on the state of the object, you actually only want to act on its status under one condition and B) your case is used in conjunction with an if statement, which is redundant - not to mention syntactically erroneous.
I think you're trying to do
if(phone.readyState == 4){
var val = phone.responseText;
alert(val);
dataInsert(val);
}else{
alert("Problemas status:"+phone.status+" state:"+phone.readyState);
}
I also think you should look into using a 3rd party library like jQuery to do your ajax.
http://api.jquery.com/jQuery.ajax/
$.ajax({
url: 'getData.html',
success: function(val) {
alert(val);
dataInsert(val);
}
});