XMLHttpRequest() post does not appear as file on server - javascript

As far as my limited understanding goes, this function should create a file on the server containing the text string returned by the function NewFileToSave():
function SaveDay()
{
var toSend = NewFileToSave();
var xhr = new XMLHttpRequest();
xhr.open('POST', 'postTest.dat', true);
xhr.onload =
function(e)
{
if (this.status == 200)
{
alert("Sent");
}
};
xhr.send(toSend);
alert(toSend);
}
When it runs (in Chrome, with no complaints from Chrome's Javascript console) the final alert gives me my text string as expected, and then the alert in the onload function tells me it's been sent, also as expected. But I get no server file called postTest.dat in the folder at the URL from which the HTML page containing the script was loaded into Chrome (or anywhere else on the server as far as a file search can tell).
Can someone please tell me how silly I am being?

That makes a POST request to the server with whatever the return value of NewFileToSave() is as the body of the request. (Since the file doesn't exist already, you'll probably get a 404 Not Found response).
If you want to create a file on the server, then you need the server to run a program that will read that data and use it to create a file (and you probably want to be using a PUT request instead of a POST request, to specify the Content-Type request header, and to add some kind of authentication/authorisation layer to the system).
The specifics of how you might go about that depend on which HTTP server you are using and your programming language preferences.
An arbitrary POST request to an arbitrary HTTP server won't create an arbitrary file. That would be a huge security hole.

Related

Do I need an XMLHttpRequest to change a JSON file value with JavaScript?

So I'm trying to make a game where people can change their display name and then store it in a JSON file so that other files and pages can access it.
So I added an XMLHttpRequest but I then read this article and wondered whether I actually need the XMLHttpRequest.
I will attach the JavaScript and JSON files to give a bit more context.
JavaScript:
var console;
let requestURL = 'displayName.json';
let request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
function sendRequest() {
request.send("displayName");
}
document.getElementById('displayName');
if (displayName = "") {
displayName = 'Soldier';
}
JSON:
displayNameData {
"displayName": ""
}
If you want the user's browser to send information to your server, you need an HTTP request.
For this reason, they are very important to web development and worth your time to learn about.
Check out one or both of these resources to dive in:
javascript.info - tutorial
MDN - reference
Note that communication with the server generally happens asynchronously so the browser can keep working on other things until the server responds. Therefore, to notice when the server responds, you need to use either
a callback function, or
a Promise object (for which you can use async/await for convenience.)
Happy coding!
You need XMLHttpRequest or fetch to make HTTP requests.
Since your JSON is at the end of a URL, you need to use one of them to read it.
The question you link to has nothing, despite the title, to do with JSON. It is dealing with the manipulation of JavaScript objects.
If you want the JSON file to provide data to your application AND you want the javascript to update it, then you need to submit your request to a server-side handler that then generates the JSON file. Currently, your code will just return the static JSON file.
It is not clear what you are trying to do with this code.

Multiple ajax calls via recursive function and DDOS-ing ourselves

In the comment by the link Jquery multiple Ajax Request in array loop the author said that making ajax requests in a loop may end up DDOS-ing ourselves.
Does that apply only a loop or multiple ajax calls in general? I mean may the risk of DDOS-ing be as well if I make multiple ajax requests via recursive function like
ajax(0);
ajax(index) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
ajax(index+1)
}
};
xhr.open('POST', 'http://example.com/ajax_handler.php');
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhr.send();
}
ps. I understand that we can "congregate all data together then send that in a single request to the server", but I need to run generating static pages passing data from the client to the server. So if there are dozens of thousands of pages I must to pass to the server via AJAX, they can't be passing as one single request because of limit of POST requests.
Why so? I would just like to keep all the logic of the generator at the client and call at the server only standard operations like reading and writing files. That is the client reads templates and content via ajax and server reading function, build page html according to its logic and pass the whole html to the server to be written in a html file
The problem Rory McCrossan was describing was if you make multiple requests at once. If you have lots of requests, you might overload the server (and/or your network connection) - you shouldn't make tons of requests at once. (Probably best to not send more than 5 request a second to a server, or something like that.)
But in your code, you're not sending out the requests at once; you only have at most one request active at any time, so the issue he was describing isn't something you need to worry about.
That said,
dozens of thousands of pages I must to pass to the server via AJAX
is a pretty odd requirement and will require a lot of bandwidth even if you don't overload the network. Consider if there's any more elegant solutions to the problem, such as generating/sending a page only when that page is requested.

Pass string securely to JS

How do I receive a string in JS (maybe through an alert) without the user being able to see it beforehand (e.g. in the source code)?
You probably know this from Geocaching Checkers, how do they secure the real Coordinates from being seen in the source code or wherever?
I have a web server and some basic JS and HTML understanding, I read about PHP and AJAX but I didn't found the solution to my problem yet.
My objective is to reveal a information only if the user completed a condition on my website, and its vital that it's not seen before.
I tried using a separate PHP file:
<?php
$koords = "N 53° 13.869 E 10° 22.716";
?>
but how do i reciev this variable in JS and can the php file be seen by the user?
In your browser (JS) it will always be available to be seen by someone with JS knowledge.
The only thing you can do is set up a server which evaluates if your user has fulfilled the condition for completing the challenge. Once the server recognizes the challenge as completed it would send back your secret to the client, so that it can be displayed to the user there. How you set up that server and with what language or framework /tools (for example PHP) depends on your background and the environment you will host your website in.
Adding a bit of detail: You will want to make a Http request in your JS somehow sending user input to the server (for example PHP). If it is simple content you could add it in the url itself with &parameter=foo, otherwise you would likely send a post request and send your data as JSON body. You would then need to evaluate the parameter in your PHP and if it meets the challenge's requirement you would answer to the client in your response with your secret or if not with a message like try again.
Ok, here is what I did, to help anyone who sees this.
The method is easy to "hack" so don't use this to hide actual sensible data, its more an obstruction to easily see in the sourcecode whats going on.
I created a PHP looking like this
<?php
$secret = "data";
$givesecret = $_GET['givesecret'];
if ($givesecret>0) {
echo $secret;
}
?>
Then, when I want the secret Information I let my JS call the PHP via XHR
var rndvar = 0;
//something is done in a loop
rndvar++;
//now something is completed and i want to reveal the secret
var xhr = new XMLHttpRequest();
xhr.open("GET", "containssecret.php?givesecret="+rndvar);
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
xhr.send();
Pretty basic, and the obvious flaw is, of course, I could call https://www.mywebsite.org/containssecret.php?givesecret=5 and it will give the secret right away, so the goal would be to name everything less obvious and don't make it clear what the criteria in the PHP is (here it is int greater then zero).
But it will always be possible to find that out if you know some coding, this is just an easy way to obfuscate and it's only relatively secure from the ordinary users. For my purpose this is well enough :-D

How to intercept uploading of email attachments with a Firefox XUL extension in outlook.com web mail

I have a XUL extension which uses a native Windows DLL and js-ctypes to encrypt files inside the local file system. I have already tested a menu driven version of it and it seems to work fine.
Now I would like to do the following: When creating a new email with attachments, be able to "catch" the attachment file and process it (meaning: encrypt it) before uploading to the composed email message. I would like to do it in a transparent fashion so the user does not have to go through the menu driven process except for providing the password for encryption.
I want to do this inside the outlook.com web based email (not Office version).
I know it is a long shot, but does anybody have an idea on where to start looking? Anybody has done something like this in the past?
Thanks in advance!
A good place to start is an addon that already does what you want (in a generic way):
https://addons.mozilla.org/en-US/firefox/addon/tamper-data/
On the download page it says Use tamperdata to view and modify HTTP/HTTPS headers and post parameters. You're interested in changing 'post parameters' so that's a good place to start.
But if you just want to implement this yourself....
I've answered this out-of-order, in order to progress in the way you might build up the solution in development.
In the final extension, you'll need to:
Intercept the request
Target the correct requests(s)
Get access to the POST request body
Parse the POST request body's form data (to get the real binary file data)
Do your encryption step
Re-encode the binary file data, re-assemble the form-data, and modify the POST request headers
Replace the existing content in POST request.
Intercepting the request & replacing the existing POST content
The basics are that you need to implement an nsIObserver passing an nsIHTTPChannel as the "subject" for observation. The "notification" you wish to observe is called http-on-modify-request.
There are simple examples (1, 2) for intercepting GET requests in the documentation for http-on-modify-request, however intercepting POST requests is more complicated.
Getting at the POST request body:
There's a mozillazine forum thread that deals with this exact topic.
Kamelot9's 2nd post in that thread details how to (1) get at the post body:
var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
var uploadChannel = httpChannel.QueryInterface(Ci.nsIUploadChannel);
var uploadChannelStream = uploadChannel.uploadStream;
uploadChannelStream
.QueryInterface(Ci.nsISeekableStream)
.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
var stream = Cc["#mozilla.org/binaryinputstream;1"]
.createInstance(Ci.nsIBinaryInputStream);
stream.setInputStream(uploadChannelStream);
var postBytes = stream.readByteArray(stream.available());
var poststr = String.fromCharCode.apply(null, postBytes);
where aSubject here comes as a parameter to your http-on-modify-request notification. You can then just modify poststr. Depending on the server, you might also need to modify the Content-length header (or your post may be truncated).
Replacing POST request content:
Once you've got your modified POST body, you need to (2) replace the existing content of the inputStream in the uploadChannel with your own:
var inputStream = Cc["#mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
inputStream.setData(poststr, poststr.length);
uploadChannel.setUploadStream(
inputStream,
"application/x-www-form-urlencoded",
-1);
// do this last - setUploadStream resets requestMethod to PUT
httpChannel.requestMethod = "POST";
Cc and Ci above are just shorthand for Components.classes and Components.interfaces respectively. These shorthand variables may already be set up, or you can define them yourself.
Parsing the form data:
I think that normally for a file upload, the Content-type: will be multipart/form-data.
To get down to the particular 'attachment' you're interested in, you'll need to:
Parse the mime envelope to get out the file attachment
Find your file attachment
Remove whatever text encoding has been used (e.g: BASE64)
In the POST headers, you'll get something like:
Content-Type: multipart/form-data; boundary=JGUOAeGT3Fjgjcdk6s35F2mPVVyTdzgR
where 'JGUOAeGT3Fjgjcdk6s35F2mPVVyTdzgR' is the MIME boundary. In the body of the POST, the content will start will be formatted like this:
--[boundary]
CONTENT-PART #1
--[boundary]
CONTENT-PART #2
--[boundary]
Each CONTENT-PART above will have some HTTP headers, a blank line, then the body of that particular CONTENT-PART.
An example from another stackoverflow question:
Content-Disposition: form-data; name="updates"; filename="update1353963418000.json"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: binary
{"collectionType":"activities","date":"2012-11-26","ownerId":"qw12er23","ownerType":"user","subscriptionId":"112233-activities"}]
In this case, the Content-Transfer-Encoding is binary (raw, encoded) UTF8, so you wouldn't need to do any more work to be able to read the JSON in the body of the CONTENT-PART.
In your case, the browser will be sending a binary file, so it'll likely have set the Content-Transfer-Encoding to base64, which means you'll need to Base64-decode the body of the CONTENT-PART to get to your real binary file. If base64data contains the encoded content, then this will give you the raw binary data:
var rawData = atob(base64data);
At that point you can do whatever encryption you want on rawData.
Remeber, you'll have to re-encode the binary data after your encryption (using btoa), then you'll need to re-assemble the multipart envelope, before re-constructing the POST request body. (Don't forget to get .length of the final request body so that you can substitute in the Content-length in the request headers.).
targetting the request(s):
That's the basic mechanism for modifying a POST request. But you've still got to single out your particular POST requests (examine the POST request URL in the observer notification) so that you allow other POST requests to proceed as normal without invoking your modification code.

Actual changing of XML file in Javascript / AJAX

since days I have been searching for answers but couldn't get what I am searching for.
I program a realtime webapp using Javascript and HTML5. For saving game stats I wanted to use a XML-file, that holds all the levelpoints and the achievements and lies locally within the same folder as the html.
So I found out, how to read out the values stored in the XML-file with an XMLHttpRequest. The problem is, that I can only change the node values client-sided, so if I empty the cache or simply reload the page, the XML does hold the original values.
To save the XML server-side is what I want. I hope, you can help me :)
Thanks in advanced!
You can use XMLHttpRequest (an AJAX request) to send the updated XML to the server and then have a server side script (using a server side language such as PHP for example) which will replace the contents of the XML file on the server.
Here's for example how you could send the XML to the server:
var xhr = new XMLHttpRequest();
xhr.open('POST', '/some_script', true);
xhr.onload = function(e) {
if (this.status == 200) {
console.log(this.responseText);
}
};
var xml = '<foo>Bar</foo>';
xhr.send(xml);
The apps that save game stats, store the data locally on the client. They don't post on to the server. If they are, then they would need internet connectivity and post data to the game server. where again there would be a PHP page or a servlet to handle data.
For client side storage, HTML5 has options. Please check the below link
http://diveintohtml5.info/storage.html

Categories