XMLHttpRequest "PUT" - javascript

I know how to "GET" data using XMLHttpRequest(), and would also like to use XMLHttpRequest() to "PUT" data to a file. The data I would like to "PUT" is just plain text. There is much on how to "GET" data, but I have done much research and have not found much on how to "PUT"data. There are a few questions online trying to do something similar but usually to "POST" instead, and none I found show a working model. Some say that for "POST"ing or "PUT"ing data, its "Content-type" must be "application/x-www-form-urlencoded" and never "text/plain". I would like to do my request synchronously and not use Node.js instead. To what I have found, this (below) seems to be the way to "PUT" data, but does not work.
How should data be "PUT" using XMLHttpRequest()?
var string = encodeURIComponent("Text String!");
var req = new XMLHttpRequest();
req.open("PUT", "example/data.txt", false);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", string.length);
req.setRequestHeader("Connection", "close");
req.send(string);
I have tried "text/plain" as the "Content-type", but the browser console gives me a "syntax error" in the resource I want to replace or tells me "no element found" if the resource is blank.

PUT creates or replaces a resource. As such, the Content-Type header field should contain the content type of the representation you are sending. For further details see section 4.3.4 of RFC 7231.

Related

JSON always returning "client_id not specified"

I'm trying to get a token from the ArcGIS Online service using a Javascript. However, it's always returning an error which indicates the client_id isn't specified.
Am I doing everything right here?
<script type="text/javascript">
var MyJSONText = '{"client_id":"<<MY_CLIENT_ID>>","client_secret":"<<MY_CLIENT_SECRET>>","grant_type":"client_credentials","expiration":"1440","f":"json"}';
var MyJSON = JSON.parse(MyJSONText);
xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.arcgis.com/sharing/rest/oauth2/token/");
xhr.send(MyJSON);
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
alert(xhr.responseText);
}
}
</script>
Edit - full error is:
{"error":{"code":400,"error":"invalid_request","error_description":"client_id not specified","message":"client_id not specified","details":[]}}
I was able to retrieve an access token using application/x-www-form-urlencoded request:
POST https://www.arcgis.com/sharing/rest/oauth2/token HTTP/1.1
User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded
Host: www.arcgis.com
Content-Length: 126
client_id=<YOUR ID>&client_secret=<YOUR SECRET>&grant_type=client_credentials&expiration=1440&f=json
which means that you might need to specify the Content-Type request header when making the XHR request:
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
and of course properly formatting the body as application/x-www-form-urlencoded instead of JSON. In my tests this endpoint didn't work with JSON payload.
Unfortunately from what it looks, the token endpoint doesn't support setting the Content-Type request header in its CORS policy which means that you might be out of luck in calling it with javascript. Besides their documentation doesn't mention anything about javascript as a supported language.
So basically if you want to make this work you could get the access token on your server side and pass it along to the client.
Access Token Generation Url =>https://www.arcgis.com/sharing/rest/oauth2/token
Headers
enter image description here
For the Case of body in Post man select 'x-www-form-urlencoded'
enter image description here
After that you will get the respective expected result with token
{"access_token":"S-z3mxAqsZBeihx8NgFmNGsZAUGfzKZWCYVV2TiQO422u9XDLTCTZAkpoecyxx_LAc71I_tPkeeOlo2Pzkapv01bBOA03SzMRjRMOm-h3ljTl-pb3XdffoyYjCflE4F8LD377DbpjDWkupkdTaxJpg..","expires_in":7200}

XHR POST with FormData object sends as Request Payload instead of FormData

I've read a handful of questions on Stack Overflow about this, but none seem to help.
I have a form, and I want to submit it. When I use a input type="submit", I can see in the headers the data goes up in the "Form Data" part of the header.
I then want to use XHR instead of the form's submit button.
I do:
var xhr = new XMLHttpRequest();
xhr.open("POST", "/url", true);
xhr.send(new FormData(document.getElementById("myform")));
Now in the header for this request, the data is there, but not in "Form Data", but in "Request Payload".
I think I can read the payload on my server (Java, Google App Engine) and parse it manually, I think. But that seems overkill.
Can I force the XHR to send the FormData as "Form Data" instead of "Request Payload"?

how to detect a proxy using javascript

in a web page, is there a way to detect by javascript if a web browser is using a PAC file http://xxx.xx.xx.xxx/toto.pac ?
Notes : the same page can be viewd behind many PACs, i don't want to use a server end language, i can edit the toto PAC file if necessary. Regards
You could make an ajax request to a known external server (google.com) and then get the headers out of that request to see if the proxy headers are in the request...
var proxyHeader = 'via';
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send();
var header = req.getResponseHeader(proxyHeader);
if (header) {
// we are on a proxy
}
Change proxyHeader to what ever your proxy adds to the response.
EDIT: You will have to add a conditional for supporting the IE implementation of XMLHttpRequest
EDIT:
I am on a proxy at work and I have just tested this code in jsfiddle and it works. Could be made prettier so that is supports IE and does an async get but the general functionality is there... http://jsfiddle.net/unvHW/
It turns out that detecting 'via' is much better...
Note that this solution will not work on every proxy and would probably only work if you are BEHIND the proxy :
Some proxies append a field in the response headers of an HTTP request which is called : X-Forwarded-For
Maybe you can achieve what you are trying to do with an AJAX request to google.com for example and check if the field is there.
Something like this :
$.ajax({
type: 'POST',
url:'http://www.google.com',
data: formData,
success: function(data, textStatus, request){
if(request.getResponseHeader('X-Forwarded-For')) !== undefined)
alert("Proxy detected !");
}
});
Edit: As Michael said, the X-Forwarded-For is only appended to requests. You'd better check for the response header your proxy puts in the response header.
No.
Browsers do not expose that sort of configuration data to websites.

How to set boundary while using XmlHttpRequest and FormData

I am trying to set the boundary correctly in the header while using FormData to post the XmlHttpRequest:
xhr.open("POST",url);
xhr.setRequestHeader("Content-type","multipart/form-data; boundary=...");
var formData = new FormData();
formData.append("filename", inputId.files[0]);
formData.append(...);
xhr.send(formData);
How do I get the boundary to be set in the request header here. I saw the request being set, the boundary is somehow created in the request. But the server has no idea on how to interpret it.
ES method
Simply don't set the Content-Type header manually and the browser will automatically set "multipart/form-data; boundary=..." value.
jQuery method
If you're using jQuery, set contentType option to false:
$.ajax({
url: url,
type: 'POST',
data: formData,
processData: false,
contentType: false
});
Try looking at this, How to send multipart/form-data form content by ajax (no jquery)? I am trying to work with this script with PHP as the reciever, having some problems with mixed results of warnings and I think my problem is that I have hacked away at the scripts both ends too much that its no longer functioning.
As for the comment by the other poster "If you're using JQuery", the only thing I have to say to that comment is that it is not helpful to the person not working in JQuery and JQ is not the be all and end all of scripts.

IE tries to download JSON in ASP. NET MVC 3

I was trying to return Json from my action and after that IE tried to download it and showed me save dialog.
I tested it in Firefox, and there it works fine.
return Json(new { success = false, message = ex.Message }, "application/json");
What is the reason of that behavior and how can I solve that issue?
After that in Javascript part I try this
if (responseJSON.success == false) {
alert(responseJSON.message);
cancel();
}
But IE doesn't show alert anyway. It brings me save dialog.
I tried to change "application/json" with "text/plain" and save dialog disappeared, but I am not able to see alert yet. What am I missing?
EDIT:
Here is my complect Javascript, I am using Valums qquploader(ex-Ajaxupload) for uploading images
var uploader = new qq.FileUploader({
element: document.getElementById("image-upload"),
action: '/Home/ImageUpload',
allowedExtensions: ['jpg', 'png', 'gif'],
sizeLimlit: 2048,onComplete: function (id, fileName, responseJSON) {
if (responseJSON.success == false) {
alert(responseJSON.message);
cancel();
}
else {
alert("success");
//some code here
}
}
});
I had tested with alert("success"); in my else part and forwarded json as "text/plain" and after that I saw the alert. But in that time responseJSON.success != false for me. Have you any suggestions about that?
I've solved that with this trick
return Json(new { success = false, message = ex.Message }, "text/html");
And now it works. But can me anyone explain why it works with text/html, and didn't work with application/json and text/plain. First is trying to download JSON and second is returning undefined properties for JSON fields.
This problem occurs when using an upload plugin that uses an iframe to do the upload with IE (tested on 9.0).
IE sets the header Accept: text/html, , application/xhtml+xml, */* and so when you reply with Content-type: application/json, it assumes it's the file (or at least that's the only explanation I could find on the web).
Thus, to circumvent that, you need to set Content-type: text/html or Content-type: text/plain.
I would recommend implementing this using an ActionFilter; instead of manually changing the content type, detect IE and a multipart POST and change the content-type accordingly.
Possibly you are not setting a correct mime type for your json content (for IE try text/plain)
See: What problems may using the MIME type application/json cause?
I was using this same uploader and had the same problem.
It has to do with the request headers sent. IE needs the request to have an accept header that indicates json.
xhr.setRequestHeader("Accept", "application/json, text/javascript, */*; q=0.01");
If you insert this after this line:
xhr.setRequestHeader("Content-Type", "application/octet-stream");
in the js file (mine is called fileuploader.js) then you should no longer have the problem, and don't need to indicate text/html in your return.
p.s.
I commented out the content-type line, but am no longer sure why. If just adding this the accept line does not work, try commenting out the content-type header as well.
Edit:
I looked at my file again, and it seems like also made another change.
Instead of the line:
xhr.send(file)
I put in:
var formData = new FormData();
formData.append("image", file);
xhr.send(formData);
This comes after the setrequesrheader line above.
I am not sure if this change will work for all uses, like multiple file upload. I only upload a single image for my use.

Categories

Resources