configuring ajaxAppender of log4javascript with Django backend - ajax

I am trying to configure ajaxAppender of log4javascript in DJango. I have made a file frontendlog.json where I want to write the logs going from the front end. This is how I write the script in myPage.html.
<script type="text/javascript" src="/static/js/log4javascript.js"></script>
<script language="javascript">
var url = '/frontEndLog/';
var log = log4javascript.getLogger("serverlog");
var ajaxAppender = new log4javascript.AjaxAppender(url);
ajaxAppender.addHeader("Content-Type", "application/json");
var jsonLayout = new log4javascript.JsonLayout();
ajaxAppender.setLayout(jsonLayout);
log.addAppender(ajaxAppender);
window.onerror = function(errorMsg, url, lineNumber){
log.fatal("Uncaught error "+errorMsg+" in "+url+", line "+lineNumber);
};
log.info("Front End Log");
alert('!!')
</script>
In my django urls.py I have this entry url(r'^frontEndLog/$', 'TryOn.views.frontEndLog'),
and in my django view I have this view function
def frontEndLog(request):
LOGGER.info ("frontEndLog")
return render_to_response('frontEndLog.json', mimetype="text/json")
So I expected the frontEndLog to be written in frontEndLog.json in the same location as other HTMLs are found in django. However, it tells me that XMLhttpRequest Request to URL returned status code 500. Can somebody please tell me where I am going wrong here and is this the correct way to use log4javascript in django?

I solved it. I printed the django request object in views.py. There I was able to find the log messages in the request.POST. It appears in the form of a dictionary since it is JSON-ified. You can access the logs with this
clientLogs = request.POST.get('data')
'data' is the key in the key : value pair here. (You can easily understand that when you see the POST object).
Whether you want to print it in the views.py itself or write it to a a txt file is up to you. So all this while the logs were actually getting logged without me being able to identify it! I guess I should have read the documentation better.

Related

Laravel pass value to javascript

Im learning laravel. I wanna ask a stupid question. Hope be helped from all of you.
When a controller return a view, I can send value blade template.
return view('home', ['message' => 'this is home page']);
I can get that from home.blade.php as:
<h1>{{$message}}</h1>
I can even send that value to javascript by the way below:
var message = "{{$message}}";
Yeah, that it!
But how can i send that value to separate javascript file.
/resources/views/home.blade.html:
<script src="/js/home.js"></script>
how can i get that value to /public/js/home.js if i dont use the way below?
<script>var message = {{$message}}</script>
<script src="/js/home.js"></script>
Thank for reading!
You can make a script tag contain all your dynamic values, and make your file
/js/home.js
use it
like this
<script>
var appSettings = {message :"{{$message}}"};
</script>
<script src="/js/home.js"></script>
so inside home.js
you can access this value
alert(appSettings.message);

Scrapy ajax POST request not working, though working in Postman

I am implementing a scrapy spider to crawl a website that contains real estate offers. The site contains a telephone number to the real estate agent, which can be retreived be an ajax post request. The request yielded by scrapy returns an error from the server, while the same request sent from Postman returns the desired data.
Here's the site URL: https://www.otodom.pl/oferta/piekne-mieszkanie-na-mokotowie-do-wynajecia-ID3ezHA.html
I recorded the request using Network tab in chrome's dev tools. The url of the ajax request is: enter link description here The data needed to send the request is the CSRFtoken contained in the page's source, which changes periodically. In Postman giving only the CSRFtoken as form-data gives an expected answer.
This is how I construct the request in scrapy:
token_input = response.xpath('//script[contains(./text(), "csrf")]/text()').extract_first()
csrf_token = token_input[23:-4]
offerID_input = response.xpath('//link[#rel="canonical"]/#href').extract_first()
offerID = (offerID_input[:-5])[-7:]
form_data = {'CSRFToken' : csrf_token}
request_to_send = scrapy.Request(url='https://www.otodom.pl/ajax/misc/contact/phone/3ezHA/', headers = {"Content-Type" : "application/x-www-form-urlencoded"}, method="POST", body=urllib.urlencode(form_data), callback = self.get_phone)
yield request_to_send
Unfortunately, I get an error, though everything should be ok. Does anybody have any idea what might be the problem? Is is maybe connected with encoding? The site uses utf-8.
You can find the token in page source:
<script type="text/javascript">
var csrfToken = '0ec80a520930fb2006e4a3e5a4beb9f7e0d6f0de264d15f9c87b572a9b33df0a';
</script>
And you can get it quite easily with this regular expression:
re.findall("csrfToken = '(.+?)'", response.body)
To get the whole thing you can use scrapy's FormRequest which can make a correct post request for you:
def parse(self, response):
token = re.findall("csrfToken = '(.+?)'", response.body)[0]
yield FormRequest('https://www.otodom.pl/ajax/misc/contact/phone/3ezHA/',
formdata={'CSRFToken': token},
callback=self.parse_phone)
def parse_phone(self, response):
print(response.body)
#'{"value":"515 174 616"}'
You can debug your scrapy requests by insersting inspect_response call and looking into request object:
def parse_phone(self, response):
from scrapy.shell import inspect_response
inspect_response(response, self)
# shell opens up here and spider is put on pause
# now check `request.body` and `request.headers`, match those to what you see in your browser

Jade html not updated after a redirect in Express.js

I'm currently having some trouble displaying a flash message in Express.js using Jade's templating engine and connect-flash. I am simply trying to flash an error message when the user tries to add a new User object to my database that already exists. However the flash message is not showing up on my page after calling router.post and redirecting back to the index (code below).
Through various console.logs and debugging, I have found that the data I am posting is indeed posting correctly, and the flash message is being set. What I have found is that on the redirect, all of the correct data is passing to the Jade template, but the variables are not being updated in the file itself. I am now wondering if this is a session related issue, or just something Flash/Jade/Express related that I am completely overlooking?
In the code below I am logging session data as well as setting the flash message to a variable. If the array for the flash message(s) is empty (i.e. on page load), an array is set with a message that says so. If the flash message(s) array contains a flash message, the test array is set with a message that says so.
index.js:
router.get('/', function(req, res, next) {
console.log(req.session);
var testArray;
var errorMessages = req.flash('user-error');
if (errorMessages.length === 0)
testArray = ['errorMessages is empty'];
else
testArray = ['errorMessages contains a message now'];
console.log(errorMessages);
console.log(testArray);
res.render('index', {
message: errorMessages,
tester: testArray,
...other irrelevant vars being passed...
});
});
router.post('/add', function(req, res, next) {
var ajaxData = req.body;
console.log(ajaxData);
User.findOne({name: ajaxData.name}, function(err, user) {
if (err) return console.error(err);
// if User DNE already in DB
if (user === null) {
...new user created and saved here...
}
/*where the important stuff begins*/
else {
console.log("flash message set");
req.flash('user-error', "A user with that name already exists!");
}
// redirect to index
res.redirect('/');
});
});
In my Jade template, I'm again logging errorMessages and testArray to make sure everything is passed to the file correctly (it is) then showing the variables.
index.jade
-console.log(message);
-console.log(tester);
.error-box Error: #{message}
.error-box Error: #{tester}
Initially loading the page, I will get the following HTML output:
<div class="error-box">Error: </div>
<div class="error-box">Error: errorMessages is empty</div>
No surprises here. But when I submit the form with data that sets the error flash message, I get the updated logs from router.get('/') and index.jade with both the correct errorMessages and testArray variables. However my HTML output remains the same:
<div class="error-box">Error: </div>
<div class="error-box">Error: errorMessages is empty</div>
Clearly the variables being passed to Jade are being updated correctly, but it appears that Jade is simply not updating the HTML. With my somewhat limited knowledge of how connect-flash and Jade work, this would lead me to believe that this is a session related issue, however my code in app.js appears to be setup correctly...
var session = require('express-session');
var flash = require('connect-flash');
app.use(session({
secret: 'secret',
cookie: { maxAge: 60000 },
resave: false,
saveUninitialized: false
}));
app.use(flash());
I am relatively new to Express.js, so I feel like there might be something small I am overlooking or don't understand, but I've tried to be as detailed as possible so I'm hoping someone can help me out here!
After more careful inspection, I found that what was really causing the issue was that res.redirect('/') was not running, as I was attempting to use AJAX on the client side to call router.post('/add').
I solved this by simply removing my AJAX request, then going back into my HTML and changing my form's attributes (the form whose data I was sending via AJAX) to include method="POST" and action="/add". This is the proper way to make a SERVER SIDE call to my router.post('/add').
I found that someone was having the same problem here, and this question initially led me to look into the AJAX/Client Side vs. Server Side issue. I found the latter question in a comment from #herbyme on this post.

Accessing Oracle ATG variables with Javascript

I am trying to pass the contents of a bean to javascript so that I can parse it and create a JSON object... (Yes I am still on ATG 9.1). However I am having trouble getting from serverside to client side.... I am new with this stuff and would appreciate any explanation as documentation on this is scarce and not helpful.
<dsp:tomap var="cartMap" bean="MyShoppingCartModifier.order" recursive="true"/>
<script>
var myCartMap = "${cartMap}";
//Logic (easy)
</script>
Doing this generates an "Uncaught SyntaxError: Unexpected token ILLEGAL" on my browser (Chrome)
Any wisdom will greatly help me in my quest in learning this stuff.
The problem is your usage of the tomap tag. You can't just pass in an entire tomap'd object because the tomap tag isn't going to create a nice, parsable json object.
You should either:
1) Format the json yourself right within your tags. Choose only the values that you want from the order.
<script>
var myCart = {
total : '<dsp:valueof bean="MyShoppingCartModifier.order.priceInfo.total">'
...
}
// Then use myCart for something here
</script>
or 2) There's a little known JSP to JSON library found here, http://json-taglib.sourceforge.net, that is very useful. To use that, you'd create a separate page, something like orderJSON.jspf, that is used to generate a pure json object from your order. Then in the page that you require this js, you can do:
<script>
var myCart = <%# include file="/path/to/orderJSON.jspf" %>
// Then use myCart for something here.
</script>

django + angularjs resource + ajax POST = 500 (Internal Server Error)

I can do GET requests, but when I do POST, in Chrome developer tools I see: "Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)"
I thought the problem is in Django's csrf_token, so I found this solution:
.config(function($httpProvider){
$httpProvider.defaults.headers.common['X-CSRFToken'] = CSRF_TOKEN;
});
In my index.html, in <head> I have:
<script>
CSRF_TOKEN = '{{ csrf_token }}';
</script>
But it still raises 500 error. Am I doing something wrong or the problem is not in csrf?
P.S. CSRF_TOKEN is declared before
<script src="{{ STATIC_URL }}lib/angular/angular.js"></script>
and other scripts.
I've figured out the problem.
Django by default appends slash to your URL. If you enter:
http://mydjangosite.com/page Django will redirect you to: http://mydjangosite.com/page/
Angular's $resource removes trailing slash (you can read about it on github: https://github.com/angular/angular.js/issues/992).
Django has APPEND_SLASH setting which uses HTTP 302 redirection to
append slash to urls without slash. This works with GET method but not
with others (POST,PUT,DELETE) because redirection cannot and will not
pass the data to the new URL
So, there are two options:
1) Use $http insread of $resource
or
2) In Django's settings.py add this line:
APPEND_SLASH = False
and in your urls.py remove all trailing slashes
simply escape the backslash like: /custom_api/get_nearest_hotels/:eventId\/
(From: http://pragmaticstartup.wordpress.com/2013/04/27/some-lessons-learnt-from-messing-with-django-and-angularjs/)
As you all know you need to dump dictionary in your HTTPRESPONCE object.
sometimes what happens, in your view; you try to dump something in to your dict that can not be serialized. that is python/django can not serialize that object.
the examples can be (FORM OBJECT), (MODEL OBJECT), etc
so you need to get those away.
context = {}
context['office_form'] = OfficeCompleteForm(request.POST)
this can not be serialized and you will get 500 error.
be free to add following data.
context['success'] = {"msg": "successfully updated. "}
context['error'] = {"msg": "error can not update. "}
and at last do not forget to call you response method like this.
return HttpResponse(json.dumps(context), content_type="application/json")

Resources