Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have the following XMLHttpRequest:
# ....
var request = new XMLHttpRequest();
request.open('GET', 'controllers/get_date.php', true);
request.setRequestHeader('Cache-Control', 'no-cache');
request.setRequestHeader('fn', 'get_date');
request.setRequestHeader('day', '27/11' );
# ....
And get_date.php looks like this:
if($_SERVER['HTTP_FN'] == 'get_date'):
$day = Common::sanitize($_SERVER['HTTP_DAY']);
$data = new MyFunction($day);
echo $data->my_data();
endif;
Basically I'm trying to get some data from $data->my_data() and all of this is working fine. However as my back-end skills are quite limited. I am wondering if this is a proper way (considering mainly security) or if I should take another approach.
You should avoid passing parameter data through HTTP header. HTTP header is for the HTTP layer to proper transport its data. It has its own purpose, but not for application parameters. Proxy, firewalls, gateways, load balancers etc could all inspect and re-write the header for the purpose of the HTTP transport. Your custom 'parameters' might get re-written, removed, or run into the same namspace of other header.
Instead, I recommend you to pass using query string using GET or POST data.
For example:
request.open('GET', 'controllers/get_date.php?fn=get_date&day=27%2F11', true);
And in PHP, getting the parameters using:
$fn = $_REQUEST['fn'];
$day = $_REQUEST['day'];
if($fn == 'get_date') {
...
Yes it's up to you!
First of all compliments for using the native XMLHttpRequest, which is supported by all browsers including the mobile ones. Using the jQuery's ajax is just performance loss.
Security
When talking about javascript there is no security. Zero.
I answered a question about How can I obfuscate(protect) JavaScript? some time ago... and there is really nothing you can hide as soon as you put it online. The only thing you can do is to annoying the "hacker". Also just using the native XMLHttpRequest increases the chance that all those jQuery fans don't understandd what you do! ;)
In the above post i used headers to validate the referrer...
Performance
XMLHttpRequest It's native... so it is the fastest approach..
All other libs include many userfriendly checks that simplify everything. Many checks means performance loss.
As you may want to use ajax for more than just one action i suggest you look at the function i wrote some time ago.
How do I return the response from an asynchronous call?
function ajax(a,b,e,d,c){ // Url,callback,method,formdata or {key:val},placeholder
c=new XMLHttpRequest;
c.open(e||'get',a);
c.onload=b;
c.send(d||null)
}
I use it for various REST API's. Mostly you don't need to set the header and other stuff.
You could modify it and add the support for adding header information.
I see a very bad thing in your code.
request.open('GET', 'controllers/get_date.php', true);
True???
Don't do that. that should be never used. Not even with static files. Ajax is meant to be async! You will crash the users browser if the response of the php file is not fast enough. By crash i mean the browser is stuck nothing moves until the ajax content is loaded. So if it takes 5seconds to load the file, for 5 seconds you can't do nothing. the mouse/touch events don't work also every animated elements will be frozen.gifs/videos/cssstyles.
How to send the params
Slightly more security... short params, best performance ?? yep, use the headers the headers are send before anything else. But in reality i think not much changes as the final binary data is probably the same size as if you would send it over GET & POST.
GET or POST?
If at the end the gained security of sending the headers is not enough so you want to do it the "normal" way, then there is only one important thing to consider: how much data you need to send. I prefer post.. it allows to send more data. I use FormData to do so.
var fd=new FormData(form);// this is the whole form including upload files.
ajax(url,callback,'post',fd);
Something that does not seem very obvious is JSON.
I see nowhere JSON mentioned. Ajax withoutJSON is useless. js & php without json is useless. you can't just send strings... so
php
//php array to jsonstring
json_encode($array);
//jsonstring to php array
json_decode($string);
js
//jsonstring to js array
JSON.parse(string);
//js array to jsonstring
JSON.stringify(array);
In both cases (if the server nginx,apache,lighthttp is setup correctly) you don't need to worry about encoding. JSON is automatically encoded in utf8.
PHP
Some ppl would probably suggest to comrpress the php(ajax can handle zipped files) or even add the correct mimetype.
//header('Content-Type: application/json'); // not needed
echo json_encode($data);
but in both cases it takes more time. so don't.
keep the php file as simple as possible. as it's the one that take more time.
don't send elements , style or other html relative stuff. you should do that clients side. to keep the server agile.
mysql to json
https://stackoverflow.com/a/20948686/2450730
Now, looking at the comments, you use NODEJS :).
Use webSockets. use it for everything.
Forget about ajax, and do everything with websockets!!!!! Bidirectional communication. And you send only the data needed. No requests, no headers... no slow stuff.
Support
Both ajax and websockets , but also server sent events are not supported by older browsers.
If that is a problem don't use those technologies. Also using jQuery to allow ajax on ie6 is just a joke....
Btw now ff, ie, opera, android, safari, ios even a 4-5 year old version of those browsers support ajax,websockets & SSE
webSockets
I really like php, mysql nginx apache... but nodejs, websockets & json ..
Thats fun pure.
simple js example.
var ws=new WebSocket('ws://YOURIP:YOURPORT');
ws.onopen=function(){ //those events are also aviable with sse
ws.send('WS open!');//sending data to the server
// server handles each user individually very easely.
};
ws.onclose=function(){
console.log('WS closed!');
};*/
ws.onmessage=function(e){
//USE JSON
var Everythingyouneed=JSON.parse(e.data);
};
# nodejs side....
https://github.com/websockets/ws
look at the broadcast or send the data to eah user individually.
Related
So I have a web page, and I would like to programaticly create a text file (lets say it has the words 'hello, I am a text file' in it) on a new directory on my website. The program will be in another directory on the website.
e.g.
https://www.example.com/txtbuild.html is trying to programaticly make https://www.example.com/texts/hi.txt
Is there a way to do this with HTML/Javascript?
EDIT:
I am on Github
You can't do it with HTML/Javascript alone, you need a functional language on the backend (nodejs, php, python)
You can use ActiveXObject, but it won't work in all browsers.
var fso = new ActiveXObject("Scripting.FileSystemObject");
var a = fso.CreateTextFile("c:\\testfile.txt", true);
a.WriteLine("This is a test.");
a.Close();
https://msdn.microsoft.com/en-us/library/5t9b5c0c(v=vs.84).aspx
If, when you say "JavaScript", you're referring to a node.js application running on a server, then this is possible. It doesn't have to be node though; it could be a Django site, or an ASP.Net site, doesn't matter. You can't have JS code in the browser create files on your server... the JS in the browser is executing on a client machine, and doesn't have access to the server's file system.
You could create an endpoint to which your clients could send requests that would initiate the creation of the file.
You could also allow clients to PUT or POST files to your server, but again, this is something you control from the server side of the application. Your webpage (i.e., HTML file as you put it) cannot create files on the server itself. Your server allows clients to send it files in a specific manner, and the client must adhere to those rules.
The short answer to your question is no.
The long answer is that you have the following alternatives:
Use a form on the Browser end, send the data back to the server, and then use a server-side language such as PHP to receive and save the data. No JavaScript required, but you do need server-side programming.
You can make the process more immediate by using JavaScript on the browser end to send data back to the server. This is called Ajax. You will still need server side processing, though.
Note that it is probably a very bad idea to simple accept user data and save it directly. There are two things you should consider in your development:
Always filter the incoming data against the possibility of receiving and accepting carefully crafted malicious data.
Consider storing the data in a database. Apart from being easier to manage (you don’t have to worry about filenames, for example), they can do less damage there.
You can achieve this in IE browser using the following code.
<SCRIPT LANGUAGE="JavaScript">
function WriteToFile(passForm) {
set fso = CreateObject("Scripting.FileSystemObject");
set s = fso.CreateTextFile("C:\test.txt", True);
s.writeline("HI");
s.writeline("Bye");
s.writeline("-----------------------------");
s.Close();
}
if you are looking for a goos reliable solution then better to use PHP and other server scripts.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm wondering, why are we still using GET method in AJAX requests for example:
$.ajax({
type: "GET",
url: "SomeController/GetSomething",
data: { id: 100}
});
GET is handy, when you want to store data in url, when you are querying Google and you want to send that query to friend or whatever else. On the other hand, we have security gaps. They are not big (I'd say they are obstacles), but it'd be slightly better to use POST when you don't want to show form data. Moreover, POST can store any type of data, control data size and hide somehow passing variables.
Is it a good solution to always use GET in places, which are not "public" (search bars, article page, user profile, ...) and use POST everywhere else? With this approach, all AJAX queries should be send using POST method.
When using POST XHR, you use a two-step process : sending the headers first and then the data, but you use Ajax for responsiveness, right ? So why use a two-step process when you can use a one-step process (GET XHR)?
Furthermore, AFAIK, GET request are cacheable, POST are not.
Last but not least, as some have pointed : HTTP verbs do have a meaning.
Keep on using GET XHR for getting datafrom server, and POST XHR for sending data.
Like you said, GET is not secure but it allows us to copy and paste links and get the same results. POST is more secure in the way it does not show the parameters directly, it still needs work on the backend to plug all the holes.
The key is not to forget why one is called "GET" and the other one "POST".
GET is accessible, so not good for anything sensitive, but easy to manipulate directly.
POST should be used to submit to the server side, sensitive or "lengthy" data.
This is only my opinion:
A savvy user who really wants to know what data is being posted will always be able to discover exactly what data is being transmitted during an http request. The only tool that you really need for this are the tools that are built into modern browsers. If you transmit using HTTPS, then a third party will be able to discern GET parameters, but not POST data, so I would say you are correct that sensitive data should only be sent as POST. Otherwise, as a security tool, POST over GET serves a similar function to a password mask on password inputs (prevent someone from looking at your data over your shoulder).
Now, to your question "Is GET better...?"
I would say that just like with synchronous http requests, you should use GET when the user or your application need to get data, and POST when your app of the user needs to post data (for persistence - in the session (like a login), or a database, etc). So it's really more of a semantic difference. Practically, you could use post for everything if you wanted to.
Ok here's my problem. I'm working on this little site called 10winstreak and I'm trying to detect if a stream is live or not with javascript because our server that we run the site off of cant handle processing every single request with PHP. The basis of detecting if a stream is live or not is you go to their XML file and in one of their tags (if it's live) it will say something along the lines of true and often time the XML file on their site will be empty if a particular stream isn't live. for example if you have a twitch.tv stream for gamespot you go to http://api.justin.tv/api/stream/list.xml?channel=gamespot and if it's got stuff in it then it's live if not then it's not.
so basically my code looks like this:
function check (URL, term){
$.get(URL , function(data){
console.log(data);
//data is whatever the server returns from the request, do whatever is needed with it to show who is live.
var number = data.search(term);
if (number > -1)
{
document.write("Live");
}
else
{
document.write("Offline");
}
});
}
and URL is a url that gets passed in and term is the term to search for in the xml file (usually "true" or "True"). but before anything happens I end up with "XMLHttpRequest cannot load http://api.own3d.tv/liveCheck.php?live_id=6815. Origin (my server's URL) is not allowed by Access-Control-Allow-Origin."
I've looked into it all over the net and i dont seem to be able to find anything that I can use. there's alot of theory stuff but not enough actual code and i dont understand the theory stuff to be able to start typing code out. from what i've seen you have 2 ways to go, use JSONP or add a line somewhere in your sever to allow for cross-domain accessing. neither of which i understand fully nor know how or what to do. It would be alot of help for someone to show me what needs to be done to get rid of this error. of course if you can explain it to a non-coder like me it would be even more awesome but at my current point, as long as the code works for all I care it might as well be magic lol.
You can solve it :)
Take a look at xReader
<script src="http://kincrew.github.com/xReader/xReader.full.js"></script>
<script type="text/javascript">
xReader("http://api.own3d.tv/liveCheck.php?live_id=6815", function(data) {
alert(data.content);
})
</script>
I think you need cacheburst option. but you can be banned from YQL.
I think its because the path is not relative. You may be calling this from a different domain/sub-domain. You can potentially allow other origins to access, which may open up a security hole or you can create a proxy locally.
In PHP creating a proxy is easy: http://blog.proxybonanza.com/programming/php-curl-with-proxy/
Now, instead of directing your request straight to that URL send the request from jQuery to your own local url and have it access it on the server side.
Another option would be to use YQL: http://www.parrisstudios.com/?p=333 (I wrote an article about this a while ago)... In that way you can turn the response into JSON, which can be accessed cross-domain (as can javascript).
You could ask for the API responses to all be returned using a JSONP server and in JSON.
You aren't going to be able to do this via client-side javascript unless they've enabled some way to retrieve their data cross-domain (CORS, JSONP, some flash widgety thing getting read permissions from crossdomain.xml file(s) located on their server...)
Short answer: unless 10winstreak offers a JSONP service, you'll have to do things on the server-side.
Slightly longer answer:
For security reasons browsers won't let you make AJAX requests from www.example.com to www.example2.com (or any other domain except www.example.com). There isn't much you can do about this except use JSONP (and you can only do that if the remote webservice offers it).
Therefore, what you end up needing to do is ask your server "hey what's on that other server?" and (since it's not limited the way a browser is) it can go get the XML from that other server. There are various ways of doing this, either with code or Apache config; not sure what's right for you, but hopefully now you understand the general principle.
P.S. See this question: Wouldn't have been simpler to just discard cookies for cross-domain XHR? if you are curious why browsers do this.
* EDIT *
I just checked out JustinTV's site, and it appears that they already have a PHP library for you to use:
https://github.com/jtvapi/jtv_php_api
This is very likely your best bet (if you want to keep using PHP that is; if not they have libraries for other languages: http://www.justin.tv/p/api).
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Client-side detection of HTTP request method
I'm working on Javascript that is injected on any page. The script is injected on servers that I'm not controlling. (Injection is done with an add-on or bookmarklet.)
The Javascript needs to know whether the page was loaded as the result of an HTTP GET or POST. The reason for this is that if the page was loaded with a GET, the URL is an identifier for the page that can be bookmarked, shared with others, etc. In case of a POST, I need to handle it differently.
Can this be done? I have found no way of accessing the request from Javascript, but perhaps there is some trick that I don't know of.
I think you can't.
Brendan Eich just confirmed that last night on his twitter, in a conversation with dhh.
Reproducing here:
#dhh: Is there any continued reason why JavaScript can't access HTTP headers in the browser outside of Ajax? And what's the historic reason?
#BrendanEich: #dhh #lostconvos no good reason -- I had no time in the old days (apart from document.cookie and navigator.userAgent), no one followed up.
#dhh: Could we just borrow the API from xhr: getResponseHeader() and getAllResponseHeaders()?
I suggest you follow both in case you are interested on this matter.
In the meantime, I think the best you can do is having two different javascripts - one for POST pages and another one for the rest. You give both to your providers and tell them how to use them. But yes, this involves cooperation from the servers.
It's not possible to directly retrieve the POST data of a webpage; Imagine that it's possible. Then, the sensitive data, submitted through a POST request can also be read, which is obviously not desired.
If you're writing an extension/userscript which has control over the generated HTML, you can append a query string to each form element with method=post. This method is only reliable if the POST requests are not scripted (AJAX), but initiated through a form.
Example code:
javascript:(function(){
var form = document.forms, i=form.length-1;
for(; i>=0; i--) {
if(/post/i.test(form[i].method)) form[i].action += "#method-post";
}
//check whether the hash contains `#method-post`
var is_post = location.hash.indexOf("#method-post") != -1;
//Optionally, remove the hash to not interfere with the scripts at the page:
//location.hash = location.hash.replace('#method-post', '');
})();
Location hashes are not submitted to the server, but passed by the browser. This solution works perfectly for extensions, but possibly inaccurate for bookmarklets, since the user should always activate it.
I have a very specific situation where a javascript page creates a new window with a meta-refresh in it which goes to a php page which has 1 variable with everything that the javascript page has put in it. Like so:
form.write('<meta http-equiv="refresh" content="0;URL=contentreq/index.php?data=');
Very long text with a lot of data (over 3000 characters)
form.write('" />');
The php page gets it like this:
$data=$_GET['data'];
$order=htmlentities(stripslashes(strip_tags($order)));
The problem is an existing app has this problem and I'm not in the situation to solve it properly so I was wondering if there is some way to encrypt/encode the data variable so that it will be a lot shorter. (My apache server does not like an 82512 characters long url...) Like tinyurl does, but PHP must be able to decode it back. I don't know the right term for it so my googling does not give me a lot of results.
The right term for this would be compression, but it won't work in this case either - the general URL length limit is 2000 characters because IE sets it that low, and if your data is tough to compress, you won't fit 3kb reliably into 2kb.
The only idea that comes to mind, if you can't store the data in a PHP session, is to "send the data ahead" using a Ajax POST request. That can carry much more than 3 kb. When the request has been sent, redirect to the next page, and have PHP fetch the transmitted data from the session or something.
It's not pretty, but the only idea that comes to my mind for this very specific scenario.
Another idea, although this is purely client-side so you can't pass on the URL, is storing the data in the browser-side local storage.
Reference:
Maximum URL length is 2,083 characters in Internet Explorer
jQuery Ajax
PHP Sessions
A URL shortening service saves hash-URL pairs and does redirects from the short URL to the long ones. This is not applicable to your case because your data URL part is dynamic.
An approach you can take is to put all your data in a cookie and let the PHP script read it from that cookie. Another option would be to POST you request to the PHP script, but this one may not be applicable.
Also note that there are differences between encryption, encoding and compression. You weren't asking for encryption or encoding, but compression.
Regards,
Alin
Compression was the term I was looking for. I've rebuilt the javascript function to do a post with the link Pekka sent. The thing now works with the bizzare long queries.
Thanks!
This is the code I've used:
document.body.innerHTML += '<form id="dynForm" action="http://example.com/" method="post"><input type="hidden" name="q" value="a"></form>';
document.getElementById("dynForm").submit();