How to call a REST API from javascript with ajax or XMLHttpRequest to upload a file using
Content-Type: multipart/form-data.
File content is in binary format, but the API which I am calling has following request format:
Authorization: Bearer <>
Content-Type: multipart/form-data
I am using following code segment to upload the file content:
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", requestUrl);
xmlHttp.setRequestHeader("Authorization", "Bearer " + token);
xmlHttp.setRequestHeader("Content-Type", "multipart/form-data");
xmlHttp.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xmlHttp.send(formData);
Where formData is the filecontent in binary format. Please suggest if this is the right way or should be handled differently.The file type I am using is an IFC file. And the error I am receiving is media-type not supported
Thanks!
For uploading files to Autodesk Forge (A360), the following curl command works in a Unix-like terminal:
curl -v 'https://developer.api.autodesk.com/oss/v2/buckets/$bucket_name/objects/$filename.ifc' \
-X 'PUT' \
-H 'Authorization: Bearer $token' \
-H 'Content-Type: text/plain; charset=UTF-8' \
-T '$filename.ifc'
since IFC files are text (ASCII) files and not binary files.
Using the same Content-Type might do the trick in your case.
Hope it helps.
Related
I'm learning how to fetch data using an API in R. I understand that the aim of httr is to provide a wrapper for the curl package.
The documentation I'm following so that I make requests to the API has the following HTTP request format. This code below will be used to generate a token
curl -s \
-d "client_id=clientid” \
-d "username=user” \
-d "password=pwd” \
-d "grant_type=password" \
-d "scope=openid email" \
"https://auth.com/token"
Afterward, I'll use the token to now communicate with the API using this request
curl --header "Content-Type: application/json" \
--header "Accept: application/+json" \
--header "Authorization: Bearer token_goes_here“ \
--request GET \
--url "https://api-sitename.org/sections?parent_id=0"
Initially, I run these two requests in a terminal and they were successful, I got a response in JSON format. My question is, how do I run these requests in an R script such that I get a responses and they're it's stored in R studio global environment? My goal is to finally load the dataset from the API to the Rstudio working environment.
T
Here is something to get you started:
library(httr)
resp <- POST("https://auth.com/token",
body=list(client_id="clientid",
username="user",
password="pwd",
grant_type="password",
scope="openid email")
)
#parse for auth token here
content(resp, "text")
get_resp <- GET("https://api-sitename.org/sections?parent_id=0",
add_headers("Content-Type"="application/json",
Accept="application/+json",
"Authorization"=paste("Bearer", token))
I was able to successfully get my API call in R by replacing the content in header to body.
Here is my code
#' Th base url
base_url <- "your/url/endpoint/for/token"
# base64 encoded client id, my end-point requires to encone the client id to base64
c_id <- RCurl::base64(txt = "clinetid:sceret", mode = "character")
#' headers
headers <- httr::add_headers(
"Authorization" = paste("Basic",c_id, sep = " ")
)
# move everything else to the body. grant_type and password were requested by the endpoint
body <- list(
username = "your username",
password = "your password",
grant_type = "password",
scope = "read"
)
#' post call to get the token
httr::POST(
url = base_url,
body = body,
config = headers,
httr::accept_json()
)
When I had the user name and password in the body, I received 400 and 403 errors. Once I moved them o the body received 200 status and the token was successfully retrieved. If you can provide what you tried in R, can help you troubleshoot.
i am new to using curl and I am trying to execute a https post request using curl. and it doest seem to work like other json post requests so i was hoping someone can explain this to me
I am not sure if i understood your answer well enough but you can take a look at this Package or this one the latter one provides provides more flexibility and features like Interceptors etc.
You can use this package Curl https://pub.dev/packages/curl
example code
import 'package:curl/curl.dart';
import 'package:http/http.dart';
final req1 = new Request("GET", "https://exyui.com/endpoint");
print(toCurl(req1));
// will print out:
// curl 'https://exyui.com/endpoint' --compressed --insecure
final req2 = new Request("PUT", "https://exyui.com/endpoint");
req2.body = "This is the text of body😅, \\, \\\\, \\\\\\";
print(req2);
// will print out:
// curl 'https://exyui.com/endpoint' -X PUT -H 'content-type: text/plain; charset=utf-8' --data-binary \$'This is the text of body\\ud83d\\ude05, \\, \\\\, \\\\\\' --compressed --insecure
final req3 = new Request("POST", "https://exyui.com/endpoint");
final part1 = "This is the part one of content";
final part2 = "This is the part two of content😅";
final expectQuery = "part1=This%20is%20the%20part%20one%20of%20content&part2=This%20is%20the%20part%20two%20of%20content%F0%9F%98%85";
req3.bodyFields = {
"part1": part1,
"part2": part2,
};
print(toCurl(req3));
I am trying to retrieve switch data via the Meraki API. Instructions and samples for the API's are here:
# https://dashboard.meraki.com/api_docs#return-a-switch-port
Sample Request
$ curl -L \
-H 'X-Cisco-Meraki-API-Key: <key>' \
-H 'Content-Type: application/json' \
-X GET 'https://dashboard.meraki.com/api/v0/devices/[serial]/switchPorts/[number]'
Sample Response
Successful HTTP Status: 200
{
"number": 1,
"name": "my port",
"tags": "dorm-room limited",
"enabled": true,
"type": "access",
"vlan": 10,
"voiceVlan": 20,
"poeEnabled": true,
"isolationEnabled": false,
"rstpEnabled": true,
"stpGuard": "disabled",
"accessPolicyNumber": "asdf1234",
"linkNegotiation": "Auto negotiate"
}
I am using Python's requests instead of curl. My code is: (NOTE I have altered the serial number and API key just for this post. I use the correct values when I run the code)
import requests
headers = {
'X-Cisco-Meraki-API-Key': '1111111111111111111111111111111111111111',
'Content-Type': 'application/json',
}
# response = requests.get('https://dashboard.meraki.com/api/v0/devices/[serial]/switchPorts/[number]', headers=headers)
response = requests.get('https://dashboard.meraki.com/api/v0/devices/1111-2222-3333/switchPorts/1', headers=headers)
print(response)
# <Response [200]>
I am getting back <Response [200]> instead of the JSON data that the API above shows.
My HTTP Status is correct, however. What am I missing in order to actually get back the JSON data?
Use print(response.content) instead of print(response).
If you want to save the data in a file, you can use:
content=response.content
data=open("name_you_want.json","wb")
data.write(content)
data.close()
use print (response.text)
instead of print(response)
because its printing response status code instead of body text and i guess you want to print response body
With .content & json.loads you should be able to parse JSON
import requests,json
response = requests.get('https://dashboard.meraki.com/api/v0/devices/1111-2222-3333/switchPorts/1')
json = json.loads(response.content)
print(json.get('name'))
To access curl using python, you can run this:
import requests
headers = {
'accept': 'text/html',
'Cookie': 'token=5e1a8b55b0249136a60423aa02b9120a845fa4122ac98ce4e771aec5d772d7d7a18ac22f18cd47727d00bddc2ebcc5cddf8a402d7a302ddffdeb7c6e15cb2a7005f857112',
}
response = requests.get("http://link-ui3.enter.com/data/1.0/auth/getUserByToken", headers=headers)
print(response.status_code)
print (r.json)
# You will get your json response
I’m playing with GitHub web hooks and I want to use curl to post some sample JSON. The request is supposed to contain a payload POST parameter with the JSON string as a value. As an example, this works:
$ curl --form payload='{"foo":1}' http://somewhere
But I need to read the JSON from a file (say foo.json). Replacing the JSON string by #foo.json posts the payload in the request body:
--------------------------8d0c6d3f9cc7da97
Content-Disposition: form-data; name="payload"; filename="foo.json"
Content-Type: application/octet-stream
{'foo':1}
--------------------------8d0c6d3f9cc7da97--
That’s not really what I want, I need the payload to be passed as a parameter. How do I do that?
Maybe silly but try this:
cat foo.json | xargs -I % curl --form payload='%' http://example.com
Just wrote this little thing and it worked:
var=`cat some.json` && curl --form payload="$var" http://lvh.me/test/index.php
Here’s an alternative Perl testing script. Pass the target URL as the first argument, feed the JSON to STDIN:
#!/usr/bin/env perl
use strict;
use warnings;
use LWP;
my $target = shift #ARGV or die "Need a target URL";
my $ua = LWP::UserAgent->new;
my $payload = do { local $/; <STDIN> };
my $response = $ua->post($target, { payload => $payload });
print $response->as_string;
I am creating an API with Tastypie and I want to access to the API from Backbone.
To send credentials I use an user_id and a api_key. I do this in android and with curl and this work great, but I can set the http header from backbone.
In curl I use:
curl --dump-header - -H "Accept: application/json" -H "Content-Type: application/json" -H "user_id: 32" -H "api_key: 69950" -X DELETE "http://127.0.0.1:8000/api/v1/deletenote/66/?format=json"
and in android java I use:
HttpDelete requestDELETE = new HttpDelete();
requestDELETE.setHeader("Content-type", "application/json");
requestDELETE.setHeader("Accept", "application/json");
requestDELETE.setHeader(Constants.HEADER_USER_ID, user_id);
requestDELETE.addHeader(Constants.HEADER_API_KEY, key);
Both of them work great, but when I try this in Backbone following the responses that I found in other post from the page, this didn't work.
I am trying this:
var removeNote = new DeleteNoteModel({id:this.model.toJSON().id},{ query:this.model.toJSON().id});
removeNote.destroy({
headers: {'user_id':dataWeb.get("id"),'api_key':dataWeb.get("api_key")}
},{
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
}
);
I'm putting the header when I call to the destroy call, but this don't send anithing to the server.
What I am doing in a wrong mode?
Thanks to all.
Tallmaris answer should fix it for you though I would recommend usign jQuery ajaxSetup method to setup the headers as default values for all ajax requests as I believe you need them all the time anyway right?
Somewhere where you launch the App put in
$.ajaxSetup({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}
});
Thanks to that you'll save yourself a lot of repeated code :) keep it DRY!
(obviously you'd need to ensure that dataWeb is available in the scope of where you launch the app :) )
It seems you are passing two parameters to destroy, pass only one containing the headers and the other options together, unless the brackets order is a typo. Try this:
removeNote.destroy({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}, // there was an extra close-open curly here...
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
});