I am trying to make an XHR with JavaScript, but I can't get it to work correctly.
When I see the right requests in the "Network" tab of the Chrome developer tools I see that they have a "Form Data" section where are listed all the informations sent with the request, like this:
Now, I've tried making my XMLHttpRequest in any way I know, but I can't get that result.
I have tried this:
var xhr = new XMLHttpRequest(),
form_data = "data%5Btumblelog%5D=drunknight&data%5Bsource%5D=FOLLOW_SOURCE_REBLOG";
// this is uri encoded: %5b = [ and %5D = ]
xhr.open('POST','https://www.somesite.com/page?' + form_data, false);
xhr.send();
But I got this "Query String Parameters" instead of "Form Data":
I have also tried this:
var xhr = new XMLHttpRequest(),
formData = new FormData();
formData.append("data[tumblelog]", "drunknight");
formData.append("data[source]", "FOLLOW_SOURCE_REBLOG");
xhr.open('POST','https://www.somesite.com/page', false);
xhr.send(formData);
But I got this "Request Payload" instead of "Form Data":
And, finally, I have tried this:
var xhr = new XMLHttpRequest(),
formData = {
"data[tumblelog]": "drunknight",
"data[source]": "FOLLOW_SOURCE_REBLOG"
};
xhr.open('POST','https://www.somesite.com/page', false);
xhr.send(JSON.stringify(formData));
But I got another "Request Payload" instead of "Form Data":
Now, my question is: how can I send my XMLHttpRequest in order to obtain the same result as shown in the FIRST image?
You're missing the Content-Type header to specify that your data is form-like encoded.
This will work:
var xhr = new XMLHttpRequest(),
data = "data%5Btumblelog%5D=drunknight&data%5Bsource%5D=FOLLOW_SOURCE_REBLOG";
xhr.open('POST','https://www.somesite.com/page', false);
// LINE ADDED
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
EDIT
FormData is generally used to send binary data and will automatically set the Content-Type header to multipart/form-data (see FormData Spec and FormData Examples). However you have to make sure the server also accepts request using this MIME-type, which apparently is not your case, as you already tried and it didn't work.
I noticed the OP tried using FormData in one of their iterations to solve the original problem.
I've recently started using the Fetch api for sending form data. It's designed with promises making it really easy to use (especially if there's a form to leverage for all of the inputs):
var form = document.forms[0];
var data = new FormData(form);
fetch(form.action, { method: form.method, body: data })
.then((response) => {
// handle response
}).catch((error) => {
// handle error
);
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Posting this as an answer because I believe it will give you exactly what you want to know;
I just want to know what sort of method is used to send that kind of data. I can assure you that the first image is obtained using an XHR
You haven't given enough information for us to see how the "correct" version is generated, but you can capture the relevant bits you want, drop in code like this before the working XMLHttpRequest is .opened;
(function (obj, methods) {
var i;
function log() {
console.log.apply(console, arguments);
}
for (i = 0; i < methods.length; ++i)
obj[methods[i]] = (function (method_name, method) {
return function () {
log.call(null, method_name, arguments);
return method.apply(this, arguments);
}
}(methods[i], obj[methods[i]]));
}(XMLHttpRequest.prototype, ['open', 'send', 'setRequestHeader']));
Now perform the action to make it fire and the relevant parameters will be logged so you can see exactly what happens to it as it is set up and sent, which should allow you to know what to pass into your one.
The problem is that I get a forbidden (403)
I'm going to assume this is not a same origin security-error because this looks server-returned and not a browser-initiated abort
Related
I'm creating a simple JavaScript code to intercept any AJAX request with the idea of add an extra param that I need to read in the server side (Java). Until now I have this code that I have tested with different kind of request, with and without jquery as well, works fine:
(function(open) {
XMLHttpRequest.prototype.send = function() {
console.log('Start a new AJAX request');
var myExtraParam = 'ABC123'; // value that I need to send, but it's dynamically, it will come from a function
open.apply(this);
};
})(XMLHttpRequest.prototype.send);
What I have been looking is the way to attach an extra parameter, on this scenario, the variable "myExtraParam" when I call the apply method.
I'm using plain JavaScript
EDIT:
As param, I'm asuming a value that I can read in the server, like when you do: myurl?myExtraParam=ABC123
Setting a parameter seems like a lot of work dealing with querystring or appending it to the request body. Safer thing seems to be using a header.
(function() {
var orgSend = window.XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function() {
this.setRequestHeader("foo", "bar")
return orgSend.apply(this, [].slice.call(arguments));
};
})();
I have a text file with the character set as "Shift_JIS" and the file contains Japanese characters. And then I do ajax request to that file as shown below.
$.ajax({
url: "demo.txt",
success: function(result){
alert(result);
}}
);
But the data that is shown in alert is not valid Japanese character. Instead it shows some junk data. Even though I tried to set the response header character set and I do many of the solution that is already before in stackoverflow, But it didn't work. Can any one help me to solve this ?
Note: Browser is Internet Explorer
You said you tried to change the charset, have you tried changing the contentType to plain text ? :
$.ajax({
/*...*/
contentType: "text/plain; charset=Shift_JIS"
/*...*/
})
You cannot read a Shift_JIS file into a string object directly in JavaScript. You have to once store the content of the file into a binary object and then decode it into UTF-16 (the internal representation of JavaScript string) with TextDecoder.
Unfortunately, jQuery's $.ajax() cannot handle the response body as binary (dataType: 'binary') out of the box. So you have to use additional module like
jQuery BinaryTransport, or use XMLHttpRequest like this:
// ref. https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
var oReq = new XMLHttpRequest();
oReq.open("GET", "demo.txt", true);
oReq.responseType = "arraybuffer"; // handle response body as binary
oReq.onload = function (oEvent) {
if (oReq.response) {
var sjisDecoder = new TextDecoder('shift-jis');
alert(sjisDecoder.decode(oReq.response)) // Note: not oReq.responseText
}
};
oReq.send(null);
I have this following js code to send an audio file to servlet. I need to send two more additional parameters to the servlet. Following is my current code
form = new FormData(),
request = new XMLHttpRequest();
form.append("file",blob, filename);
request.open(
"POST",
"AudioToText",
true
);
request.send(form);
CAn anyone help me with js code how to add additional two parameters like id/pass in this request and how to fetch them in the servlet. Thanks in advance.
The second param in request.open() suppose to point to the file that will process the data in absolute an absolute link, there's also another property of the XMLHttpRequest type called onreadystatechanged which expects a callback that will check to see whether or not the request was successful
Example Code - ignore the lines with self, this those are just variables pointing to methods/properties and are not dependent to perform a request:
// if an Object to connect to server was created begin transfer
if (this.xhr) {
var processData = function () {
// if everything is ok carry on
if (self.xhr.readyState === 4 && self.xhr.status === 200) {
if(self.responseType === "text"){
self.Success(self.xhr.responseText);
}else{
self.Success(self.xhr.responseXML);
}
}
// if something fails along the way else execute failure method
else if (self.xhr.status !== 200 && self.xhr.readyState === 4) {
// something went wrong
}
};
// open connection
this.xhr.open(this.method, this.host, true);
// set up the connection to a method to process the data
//noinspection JSPrimitiveTypeWrapperUsage
this.xhr.onreadystatechange = processData;
// send the data
this.xhr.send(this.postData);
I'm very new at this. I've read books to learn javascript and HTML, so unfortunately I haven't learn much about this.
I never used AJAX before, so not sure how it works, searched online, but find all examples too complicated.
Basically what I want to do is save a playlist (although not with cookies). Something everyone can see and add-on to it (similarly to a comments section).
This is just an example, I'm doing something else, but the html + js would be a bit big. Just want to know how I would do it on this, so that I could understand it (hopefully) and apply it elsewhere.
This would be the body and below it the code I have (currently all my code is in [head]):
<body>
<form>
<input type="text" id="songInput" size="40" placeholder="Song Name">
<img id="addButton" src="button.png">
</form>
<ul id="playlist"></ul>
</body>
<script>
window.onload = load;
function load() {
var button = document.getElementById("addButton");
button.onclick = buttonClick;
}
function buttonClick() {
var text = document.getElementById("songInput");
var song = text.value;
var button = document.getElementById("addButton");
var add = document.createElement("li");
add.innerHTML = song;
var ul = document.getElementById("playlist");
ul.appendChild(add);
}
</script>
First you have to understand what AJAX is. AJAX is not a "tool" that you can use, instead, it's a name for the techniques (asynchronous JavaScript + XML). Basically it means "getting/posting data from/to server."
In vallina JavaScript, XMLHttpRequest lets you send and receive data to and from a server:
var xhr = new XMLHttpRequest(); //Create an XMLHttpRequest object
xhr.open('get', url); //Set the type and URL
xhr.onreadystatechange = function(){ //Tell it what to do with the data when state
// changes
if(xhr.readyState === 4){ //4 is the code for "finished"
if(xhr.status === 200){ //Code 200 means "OK"
//success
var data = xhr.responseText; //Your data
}else{
//error //Deal with errors here
}
}
};
xhr.send(null); //After finished setting everything, send the
// request. null here means we are not send-
// ing anything to the server
It might look complicated, and xhr is repeated quite a lot. Not to mention the problems that we have to deal with when executing in IE.
There is solution for that. We will use libraries to simplify the process and let it do the hard works for us.
In jQuery, this is what you have to do to for a basic XMLHttpRequest:
$.ajax({
url: url,
data: { /*data here*/ },
type: /*"GET" or "POST"*/
}).done(function(data){
//success
}).fail(function(){
//error
});
//Not complicated at all with jQuery
Since AJAX is a group of techniques to send/receive data, there're more ways to do the "same" thing. You might realize the code above only works for URL that has the same domain (pages on your server). To bypass that limitation, there's another technique called JSONP. Sounds fancy, but what it means is simply "using the <script> tag to get pass that limitation". And of course, jQuery got you covered:
$.ajax({
url: url,
data: { /*data here*/ },
type: /*"GET" or "POST"*/,
dataType: "JSONP" //specifying dataType to be JSONP
}).done(function(data){
//success
});
Here is a simple example of getting content off Wikipedia using JSONP: http://jsfiddle.net/DerekL/dp8vtjvt/
With a normal XMLHttpRequest call to Wikipedia's server would not work. However by exploiting the fact that script tags are not restricted by the Same-Origin Policy we can achieve the same thing. Note that for JSONP to work, the server must be programmed internally to allow returning a JSON with wrapped callback call.
I have a javascript file which has a function calling a server (url) to get information. Here is the javascript function:
sendQuery = function(devstr) {
var baseUrl = 'http://serverurl/' + devstr;
alert("the url is " + baseUrl);
$.ajax(baseUrl, {
type: 'GET',
dataType: 'json'
}).done(function(results){
return results;
}).fail(function(e) {
showError(e);
});
}
and from actionscript I am calling this function as follows:
var result:String = ExternalInterface.call("sendQuery", parameter) as String;
The call actually happens (I got an alert from javascript with the right url) but then result is simply empty or null. There is no result coming back. I added an alert to "done" in javascript and that alert does not get called.
I tried to use ExternalInterface.addcallback but I can't pass parameters and I am not entirely sure if that will work either.
I am not entirely sure to make the call from Actionscript to the Javascript file, which calls the server, and then get the information back to actionscript so I can parse it and do more with it.
I also should note that some of the operations I will be performing require POST operations. The reason I didn't do this through actionscript is because it requires having a crossdomain.xml file on the server I am requesting this information from.
Thanks in advance for the help.
What you are trying to do, can be done without Javascript in pure ActionScript3.0 by URLLoader class:
var baseUrl:String = 'http://serverurl/'+parameter;
var request:URLRequest = new URLRequest(baseUrl);
request.contentType = 'application/json';
request.method = URLRequestMethod.GET; //For 'POST' request-> URLRequestMethod.POST
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, function(e:Event):void{
var result:* = e.target.data;
});
urlLoader.load(request);