Put a custom http header in backbone - http

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);
}
});

Related

NextJS, fetch, multipart/form-data, missing boundary

I've faced with issue while proxy http request with multipart form data by NextJS. I have to send file from a client fide to next js, after that - to FastApi service.
The problem was:
fetch("https://127.0.0.1:3000/api/newfile", {
method: "POST",
headers: { "Content-Type": "multipart/form-data" },
body: new FormData(form)
});
headers request: "Content-Type: multipart/form-data"
In order for NextJS API to parse the file, you need a header with boundary
Something like this:
multipart/form-data; boundary=----< generate boundary >
For a long time I could not figure out how to get it.
There is an exit. It is necessary not to fill in "Content-Type".
And then the browser itself will generate this header by passing the form-data.
For example:
fetch("https://127.0.0.1:3000/api/newfile", {
method: "POST",
headers: {},
body: new FormData(form)
});
I also noticed that the problem concerns fetch
When I used XMLHttpRequest I didn't face such problem.
Further, the header can easily be passed further to FastAPI
in API:
req.headers["content-type"]

Flutter HTTP request with JSON data to a Firebase function

I am currently trying to set up our Firestore database for a Flutter mobile app to take data from a Firebase function and store it into the database. Currently, we are trying to pass an HTTP request to our URI and attach some JSON data to it.
My function is as follows:
exports.testFunction = functions.https.onRequest((request, response) => {
var data = {
name: request.body.name,
age: request.body.age
};
var setDoc = db.collection('users').add(data);
response.json({result: `User ${data.name} at age ${data.age} added.`});
return;
});
Currently, the data can be retrieved when using a web browser and requesting from https://us-central1-[project-name].cloudfunctions.net/testFunction?name=[string]&age=[int]. This also works within our Flutter app, using the entire URL as a single argument with no body. However, when trying a cURL request from the command line:
curl -H 'Content-Type: application/json' -d '{"name": "[string]", "age": [int]}' https://us-central1-[project-name].cloudfunctions.net/testFunction
Hypothetically, the data should be in request.body, but I am getting an error saying the request could not be handled. What exactly is going wrong here?
Later, we want to implement this request in a Dart/Flutter app by attaching the JSON object to the body of the http.post. Is there a missing link in between this process that I'm missing?
The error Request body is missing data means that the payload that's being sent in the request needs to be mapped inside data. It's mentioned here in the docs that the Request body should have a data field.
var data = {
'data':{
name: request.body.name,
age: request.body.age
}
}

Different behavior CURL vs http.get - CORS

So, I am really getting annoyed at this:
Command line:
$ curl -X GET "cloudant/url" --header "Authorization: Basic YWRtaW46cGFzcw==" --header "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
{ "response": "OK" }
With Angular 2 http module (inside of an injectable service):
import {Http, Response, Headers} from '#angular/http';
let headers = new Headers();
headers.append("Authorization", "Basic YWRtaW46cGFzcw==");
headers.append("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
this.http.get("cloudant/url", { method: "GET", headers: headers });
405 (Method Not Allowed)
Response for preflight has invalid HTTP status code 405
I should not, nor need to, care about the server configuration. I want to emit a GET request to the server, and any CORS client-sided security concerns are none of my business.
Can I make Http behave like curl in this particular regard?
This is exactly what CORS is intended to do. It prevents you from making cross origin requests from your browser unless the server is set up to specifically allow it. I understand your frustration, but there is no workaround for this.
You're mistaken in thinking that CORS is simply a client side security concern. It takes a well configured server coupled with a well designed front end app to build something really great. And you should care about the server configuration as much as it ensures that you are able to deliver a responsive and snappy front end experience. If any website in the world could just start hitting this API there would be all kinds of additional security and performance concerns for the backend.
I used the fetch API instead:
return fetch(url, { method: "GET" }).then(this.extractData).catch(this.handleError);
...
private extractData(res: Response): Promise<CloudantCheckStatisticsRowMapping> {
let p = res.json();
return p.then(function(body: any) {
console.log("Found " + body.total_rows + " records; last one is the one we need.");
return body.rows[0].doc;
});
}
It seems it's not bothered by the CORS.

Convert cURL to Google Apps Script

I am trying to convert a cURL command to a Google Apps Script PUT request.
I came up with the below google script but it does not seem to work. When I change the URL of both of these to RequestBin in order to probe what the server side is getting, RequestBin shows that the raw source of both of these come through as exactly the same. Yet, only the cURL command is able to perform the desired action (update a file on github) when I change it back to the github URL.
curl -i -X PUT -H 'Authorization: token yadayda' -d '{"path":"mygeojson.json","message":"Initial Commit","committer":{"name":"Sidd","email":"siddsubra#gmail.com"},"content":"bXkgbmV3IGZpbGUgY29udGVudHM=","sha":"0d5a690c8fad5e605a6e8766295d9d459d65de42","branch":"master"}' https://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json
cURL Command
And this is the Google Script
function mainscript() {
var sha = getSHA();
var authenticationToken = "yadayada";
var url = "http://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json";
var headers = {
"Authorization" : "token " + authenticationToken,
};
var payload = {
"path": "mygeojson.json",
"message": "Initial Commit",
"committer":{
"name": "Sidd",
"email": "siddsubra#gmail.com"
},
"content": "bXkgbmV3IGZpbGUgY29udGVudHM=",
"sha": sha,
"branch": "master"
};
var options = {
"headers" : headers,
"method" : "PUT",
"payload" : JSON.stringify(payload)
};
Logger.log(options);
Logger.log(UrlFetchApp.fetch(url, options));
}
Google Apps Script
I recently did a script that call a request to a API from scrapy cloud, and had a dificulty to convert curl to App Script request too.
I noticed that payload doesn't worked when i used JSON.stringify, so try remove it from payload:
"payload" : payload
Other observation was the need to use Utilities.base64Encode in authentication token:
headers = {"Authorization":"Basic " + Utilities.base64Encode(authenticationToken + ":" + "")}
See this sample:
url = "https://app.scrapinghub.com/api/run.json"
headers = {"Authorization":"Basic " + Utilities.base64Encode("myToken" + ":" + "")}
payload = {"project":"327107", "spider":"pmp"}
options = {"headers":headers, "payload":payload}
response = UrlFetchApp.fetch(url, options)
data = JSON.parse(response.getContentText())

I see the response body in chrome developer tools, but unable to retrieve it inside Front End

I am currently working in a project where I need to send a response from grails back end to ReactJs front End. I was able to send the response from grails controller using "response" but unable to extract the response body on the ReactJs side. I tried checking in the following and found null value or undefined.
response.content, response.body
I see the response I sent back from grails in chrome web developer tools "Network" tab. but unable to find out which field of response object actually has it. Any help regarding this will be highly appreciated.
My http request.
post: function(url, item) {
return fetch(baseUrl + url, {
headers: {
'Accept': 'text/plain',
'Content-Type': 'text/plain'
},
method: 'post',
body: item
}).then(function(response) {
alert(response);
return response ;
});
},
grails
response << "there is an error"
Try render 'there is an error'
Or if you need to render JSON:
render [someKey: 'there is an error'] as JSON
To understand how grails controllers and views work read this simple example.
Have you tried content-type: 'application/json'

Resources