Difference between Electron-based XMLHttpRequest and browser-based URL with query string? - javascript

I'm working on an Electron app and trying to integrate the Easy Digital Downloads Software Licensing WordPress plugin. I haven't done much with HTTP communication in Electron/Javascript so this may be a naive question.
The problem: I am able to get a license activation response from my EDD server and while there is no specific error, for some reason a license is not activated. The odd thing is that if I use a URL and query string in a browser with the same data, the plugin responds as expected: I can activate, deactivate and check the status of a license.
So EDD seems to be working and there are no errors with Electron. But something is missing. Initially I was using the net Electron module but after this issue came up, I switched to using the example script from EDD (below) which uses XMLHttpRequest. With that I get the following response back:
{"success":true,"license":"valid","item_id":539,"item_name":"My
Awesome App","license_limit":1,"site_count":0,"expires":"2020-12-19
23:59:59","activations_left":1,"checksum":"f2d66c6844b37d1fa931b813c408",
"payment_id":248,"customer_name":"Marvin
Gardens","customer_email":"marvin#home.com","price_id":false}
Which is fine except that "activations_left":1 never changes and it should given "license_limit":1. So something is wrong.
On the other hand, if I use a URL with a query string in a browser, the "activations_left" is decremented and license activation only works once (as it should). For example, this works:
http://YOURSITE.com/?edd_action=activate_license&item_id=8&license=cc22c1ec86304b36883440e2e84cddff&url=http://licensedsite.com
My Question: is there some fundamental difference between these two methods? Is there something I need to add to my XMLHttpRequest? I have a support ticket open with EDD but I need to keep moving with this. And sorry to be so long-winded!
UPDATE:
#aw04 suggested I try using GET – just tried that and I "get" the same response as before: no error but also no activation.
Could there be some property which should (or shouldn't) be in the Electron request which is (or isn't) in a browser request by default?
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
console.log('xhttp.responseText', xhttp.responseText);
}
}
var url = "http://YOURSITE.com/?edd_action=activate_license&item_id=8&license=cc22c1ec86304b36883440e2e84cddff"
xhttp.open("GET", url);
xhttp.send();
var xhttp = new XMLHttpRequest();
var postUrl = 'http://<domain.com>/edd-sl/';
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
console.log(xhttp.responseText);
}
}
var data = {
edd_action: 'check_license',
license: '<license key>',
item_name: encodeURIComponent('<item name>'),
};
xhttp.open("POST", postUrl, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.setRequestHeader("Access-Control-Allow-Origin", "http://local.dev");
var values = '';
for (var key in data){
values += key + '=' + data[ key ] + '&';
}
values = values.substring(0, values.length - 1);
xhttp.send(values);

Based on some help from Easy Digital Downloads support folks, this is resolved.
The issue had to do with a property in their Software Licensing plugin setup: "Do not check URL". I hadn't enabled that with the result that my API call from Electron failed and the one using a browser succeeded because the browser was adding headers that Electron was not.
After enabling "Do not check URL", calls from within Electron work. I guess there is also an option to pass in a URL, but since I am using EDD for licensing desktop software, that didn't seem like a needed option.
Anyway, hope this helps someone.

Related

How can I stop caching when using AJAX to read a file?

I'm currently building a website that uses AJAX to dynamically update sections of the page without the need to refresh, however, when I change aspects of the file that AJAX reads the website sometimes takes minutes to update even though the file is read about once per second. Whilst looking for the issue I found that I can turn caching off by using the developer tools and this then allowed the website to update at the appropriate speed.
Here's the code I am using:
var path = "Path of the json file i am reading"
var state;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
state = JSON.parse(this.responseText);
}
};
xhttp.open("GET", path, true);
xhttp.send();
I've been looking for a while now and the only advice I can see about what to do about the cache is to use the developer tools to turn it off. Is there any way I can implement some code to automatically tell the browser to not cache the file being read?

Editable javascript and Ajax

Well I have a non-jQuery ajax function:
function callAjax(){ //will be sent to node server
var xmlhttp;
// compatible with IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
canAjax = true;
//do something
}
}
xmlhttp.open("GET", "string", true);
xmlhttp.send();
}
and a function that calls it:
function a(){
if(mouseIdle && canAjax){
callAjax()
}
}
This is kind of an api I give to my clients with a following:
<script src = "mysrc">
the problem is, anyone can easily delete these if's if they wanted(including their clients), and I can't figure out a way to make it uneditable, or at least preventable. I just want my javascript code to be untouchable from the inside, how can it be done?
Like Quentin said, you can't control JavaScript on the client side, that's just how the web works.
You could implement a simple auth system using tokens.
Your token should be something hard to guess to discourage brute force attacks, like the SHA256 hash of the current time. The empty hash for sha256 is below:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Then you could save this token key in your database (MongoDB, MySQL or other) and you need to obligate your client to send their token in each request they make.
After this you just need to validate the usage quota to that key and decide if you should serve or not.
It can't.
Anything you send to the client can be edited by the end user or duplicated, edited and placed on another website.
If you want to limit accesses to your Ajax endpoint, then you'll need to put the protection in on the server. For example, with IP address linked rate limiting.

Get text from a link in javascript

I am trying to get text from a service on the same server as my webserver. The link is something like this:
http://<OwnIPadres>:8080/calc/something?var=that
This is my code:
function httpGet(theUrl)
{
alert(theUrl);
var doc = new XMLHttpRequest();
doc.onreadystatechange = function() {
if (doc.readyState == XMLHttpRequest.DONE) {
alert("text: " + doc.responseText );
document.getElementById('ctm').text = doc.responseText;
}
}
doc.open("get", theUrl);
doc.setRequestHeader("Content-Encoding", "UTF-8");
doc.send();
}
The url that i print in my first alert is the good one if i test in my browser, it is an html page with a table in it. But the alert of my text is empty? Is it a problem that the text is html?
Actually, its quite ok that your 'text' is 'html'. The problem is that using a different port counts as cross-site scripting. Therefore, your XMLHttpRequest is being stopped by the browser before it actually reaches your page across port 8080.
I'm not sure what else you're doing before and around this code snippet, but you could try an iframe call to your url to get your data, or you could add an
Access-Control-Allow-Origin: http://:8080/
in your header (however that will only get you the most modern browsers).
Finally, you could pull in a JS framework like JQuery which could help you with pulling in this service data.

XMLHttpRequest to the MongoDB simple rest interface

I am a beginner in both Ajax and MongoDB. I was hoping to visualize some of the data in my MongoDB using a web browser (which, for the moment, is running on the same host). For this, I thought it might be possible to get the data using XMLHttpRequests. I am running MongoDB with the --rest option and I checked that when I load hxxp://localhost:28017/test_db/ss_test/
on Firefox, I get the proper reply (a JSON document with the data in the ss_test collection of the test_db database). So far, so good.
I then wrote the following JavaScript function which I connected to the "onclick" of a button:
function makeRequest()
{
var myrequest = new XMLHttpRequest();
myrequest.onreadystatechange = function()
{
alert("status=" + myrequest.status + " readyState=" + myrequest.readyState)
if (myrequest.status == 200 && myrequest.readyState == 4)
{
// ...do something with the response
}
}
myrequest.open("GET", "http://localhost:28017/test_db/ss_test/", true);
myrequest.send();
}
So, when I load the html file on Firefox, open the console and click on my button, I see that the http request is indeed made, the status code is "HTTP/1.0 200 OK" and a response with Content-Length: 219257 is delivered, which looks great. However, the XMLHttpRequest object does not report the status=200. The alerts that pop up report a constant status of 0 as the readyState progressively becomes 1, 2 and 4 and my if statement is never true.
Could anyone please tell me what I am doing wrong? In the beginning I thought it was because my html was loaded on the browser by the file protocol or that I was seeing some same-origin policy related issue, but then I put the html file on a web server on localhost and loaded it from there and nothing changed. Thank you very much for any replies!
you need to create a function to handle the request.
http://www.ibm.com/developerworks/web/library/wa-ajaxintro2/
http://www.ibm.com/developerworks/library/wa-ajaxintro3/
function makeRequest()
{
var myrequest = new XMLHttpRequest();
myrequest.onreadystatechange = create_this_function()
{
}
myrequest.open("GET", "http://localhost:28017/test_db/ss_test/", true);
myrequest.send();
}
#
function create_this_function()
{
alert("status=" + myrequest.status + " readyState=" + myrequest.readyState)
if (myrequest.status == 200 && myrequest.readyState == 4)
{
// ...do something with the response
}
}

Reading from a http-get presenting in Firefox bookmarks

I'm trying to get a Firefox plugin to read data from a HTTP get, parse the results and present them as links in a bookmark-like drop-down menu.
My quesion then is: Does anyone have any sample code that will do this?
Having never developed one myself, I'm not certain how this is typically done in Firefox plugins, but since plugin scripting is JavaScript, I can probably help out with the loading part. Assuming a variable named url containing the URL you want to request:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.onreadystatechange = function() {
if(this.readyState == 4) { // Done loading?
if(this.status == 200) { // Everything okay?
// read content from this.responseXML or this.responseText
} else { // Error occurred; handle it
alert("Error " + this.status + ":\n" + this.statusText);
}
}
};
xmlhttp.send(null);
A couple of notes on this code:
You may want more sophisticated status code handling. For example, 200 is not the only non-error status code. Details on status codes can be found here.
You probably want to have a timeout to handle the case where, for some reason, you don't get to readyState 4 in a reasonable amount of time.
You may want to do things when earlier readyStates are received. This page documents the readyState codes, along with other properties and methods on the XMLHttpRequest object which you may find useful.
Robert Walker did a great job of describing how to send the request. You can read more about Mozilla's xmlhttprequest here.
I would just add that the response would be found (using Robert's code) using
xmlhttp.responseText
(Edit - i didn't read closely enough, thanks Robert)
You didn't indicate exactly what the data was, although you mentioned wanting to parse links from the data. You could the xmlhttp.responseText as an xml document, parse out the links, and place it into a menulist or whatever you like.

Categories