Invalid Json response u or e etc - javascript

In WIX Backend, I'm struggling to find a way to upload a file to Dropbox using JS, fetch, etc....
I'm getting the following error. In addition where I need to mention the file I want to upload to Dropbox?
invalid json response body at https://content.dropboxapi.com/2/files/upload reason: Unexpected token E in JSON at position 0"
import { fetch } from 'wix-fetch';
export function xdrop() {
const url = "https://content.dropboxapi.com/2/files/upload";
const headers = {
"Authorization": "Bearer " + 'here I wrote of course my token code',
"Content-Type": "application/json",
"Dropbox-API-Arg": JSON.stringify({
"path": "/accwix.csv",
"mode": {
".tag": "add"
},
"autorename": true,
"mute": false
})
}
const request = {
"headers": headers,
}
console.log("request==>", request)
return fetch(url, request)
.then(response => response.json());
}

Related

how can i send token to backend i n vue js

i'm trying to make payment to my backend, but each time i send the payment i get this message from my backend
{
"success": false,
"message": "No token Provided"
}
my backend requires authentication
this is my script tag
methods: {
sendTokenToServer(charge, response) {
const token = localStorage.getItem("token");
axios
.post(`http://localhost:5000/api/pay`, {
headers: {
Authorization: "Bearer" + token,
"x-access-token": token
},
totalPrice: this.getCartTotalPriceWithShipping,
})
.then(res => {
console.log(res);
});
}
}
};
</script>
when i check my dev tool i see my token
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ"
this is my backend headers
let token = req.headers["x-access-token"] || req.headers["authorization"];
please how can i go about this
your code looks fine, just create an object then add it to the url i guess your looking for something like this.. try this
methods: {
sendTokenToServer(charge, response) {
var request = {
totalPrice: this.getCartTotalPriceWithShipping,
};
const token = localStorage.getItem("token");
axios
.post(`http://localhost:5000/api/pay`,request, {
headers: {
Authorization: "Bearer" + token,
"x-access-token": token
},
})
.then(res => {
console.log(res);
});
}
}
First parameter is your url,
Second parameter is your data,
Third parameters is your config.
You can make a post request like below
axios
.post(
`http://localhost:5000/api/pay`,
data,
{
headers: {
"Authorization": `Bearer ${token}` //mind the space before your token
"Content-Type": "application/json",
"x-access-token": token,
}
}
);
NOTE: data is your request body.
e.x.
{
"firstname": "Firat",
"lastname": "Keler"
}

Why axios request doesnt work(Maybe problem in headers or CORS)?

The following Axios request made via a local server on Redux does not work, giving a CORS error:
axios.post('server_url', qs.stringify({
"username": "123",
"password": "123",
"repassword": "123"
}, {
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
}))
But the request is made through Postman, and even the following python code:
import requests
from requests.structures import CaseInsensitiveDict
url = "server url"
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
headers["Content-Type"] = "application/x-www-form-urlencoded"
data = "username='123'&password='123'&repassword='123'"
resp = requests.post(url, headers=headers, data=data)
print(resp.content)
There is no access to the server from the word at all. Maybe it's some kind of headings or something like that?
Error in console
Error in network
A message or any request through axios must return a promise because the request to the server is an asynchronous operation.
For example:
const url = "http://somedomen.org";
axios.post(
url,
{ name: "John", pass: 1, repass: 1 },
{
headers: {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
},
).then(res => {
return res.data
})
Also you can use async/await sintaxis
async function func() {
const url = "http://somedomen.org";
const response = await axios.post(
url,
{ name: "John", pass: 1, repass: 1 },
{
headers: {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
},
)
return response.data
}
Or to destructure the response variable
async function func() {
const { data, status, headers } = await axios.post(
//your condition...
);
return {
data,
status,
headers,
};
}
Until you have returned the promise of a result, the request cannot be completed.
I hope I helped you

Parsing multipart/mixed responses with Node.js and axios

I've trying to parse a multipart/mixed response with (1) JSON and (2) .zip file.
I've been using Axios to GET the response, no problem there. I've seen npm packages like meros and multipart-mixed-parser but both just returned an empty array.
the response looks like
--Boundary_137_1895017408_1627074248456
Content-Type: application/json
{
"createdDate" : "2021-07-22T01:46:05.149+0000",
more JSON...
}
--Boundary_137_1895017408_1627074248456
Content-Type: application/octet-stream
Content-Disposition: form-data; filename="347b3bd1-e6e3-49a0-928d-9956df5c5af11671844264911435718.tmp"; modification-date="Fri, 23 Jul 2021 21:04:08 GMT"; size=620991; name="attachments.zip"
binary data here ...
--Boundary_137_1895017408_1627074248456--
async function eManGet (mtn, zipPath) {
try {
mtn = mtn.toUpperCase()
if (zipPath) {
const res = eManAPI.get({
url: `/emanifest/manifest/${mtn}/attachments`,
headers: {
Accept: 'multipart/mixed'
}
})
return res
} else {
...
}
// console.log(res.data)
} catch (error) {
...
}
}
The package I want to use this for is here
If you've faced this problem before, what package(s) did you use?
The dicer npm package does the job pretty well. You'll have to extract the boudary from headers yourself tho.
How to send multipart/mixed with axios
There is example of source code with request
const messages = body[endpoint].map(function (m) {
return {
'Content-Type': 'application/http',
body: 'GET ' + api + '/gmail/v1/users/me/' + endpoint + '/' + m.id + query + '\n'
}
})
const r = request({
method: 'POST',
url: api + '/batch/gmail/v1',
multipart: messages,
timeout: opts.timeout,
headers: {
'Authorization': 'Bearer ' + key,
'content-type': 'multipart/mixed'
}
})
from this library
https://github.com/SpiderStrategies/node-gmail-api
To solve this problem I used request catcher and wrote the following tests:
it('request catcher of request', () => {
const catcher = 'https://pl.requestcatcher.com/';
const messages = [1,2,3].map(function (index:number) {
return {
'Content-Type': 'application/http',
body: 'GET ' + `/gmail/v1/users/me/${index}\n`
}
})
const r = request({
method: 'POST',
url: catcher,
multipart: messages,
headers: {
'Authorization': 'Bearer KEY',
'content-type': 'multipart/mixed'
}
})
expect(r).toBeNull();
})
and saw the following request on catcher:
For axios there is not ready answer in all internet. This is my research:
You can use a FormData object in the browser. In Node.js the feature isn't supported yet by axios (see #789).
https://github.com/axios/axios/issues/803
[RFC2388] suggested that multiple files for a single form field be
transmitted using a nested "multipart/mixed" part. This usage is
deprecated.
https://datatracker.ietf.org/doc/html/rfc7578
info how to do it in request ( that is also depreciated )
https://github.com/request/request#multipartrelated
Function for generation boundary
https://github.com/form-data/form-data/blob/53adbd81e9bde27007b28083068f2fc8272614dc/lib/form_data.js#L347
So we can send multipart/mixed by this code
it('request catcher of axios', () => {
const catcher = 'https://pl.requestcatcher.com/';
const r = axios.post(catcher, `--3e50fc2b-7a5c-4565-99f2-1628010018be
Content-Type: application/http
GET /gmail/v1/users/me/1
--3e50fc2b-7a5c-4565-99f2-1628010018be
Content-Type: application/http
GET /gmail/v1/users/me/2
--3e50fc2b-7a5c-4565-99f2-1628010018be
Content-Type: application/http
GET /gmail/v1/users/me/3
--3e50fc2b-7a5c-4565-99f2-1628010018be--`,{
headers: {
'Authorization': 'Bearer KEY',
'content-type': 'multipart/mixed; boundary=3e50fc2b-7a5c-4565-99f2-1628010018be'
}
})
expect(r).not.toBeNull();
})
and now oly generation of boundary is problem to solve. Lets check differences between multipart/mixed and and multipart/form-data bounduaries.
This is exmple of bounduary from form-data package:
--------------------------942880057551350107765038
and this is from mixed (from request):
--3e50fc2b-7a5c-4565-99f2-1628010018be
and this is proper RFC
https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
so we can use this code
> `--${crypto.randomUUID()}`
'--7784084f-e129-44ea-aa64-8f480a26c75f'
And this is code that sends mutipart/mixed by axios
it('request catcher of axios', () => {
const catcher = 'https://pl.requestcatcher.com/';
interface SingleMultipartMixedMessage {
'Content-Type': string,
body: string
}
const messages = [1, 2, 3].map(function (index: number) {
return {
'Content-Type': 'application/http',
body: 'GET ' + `/gmail/v1/users/me/${index}\n`
}
})
const boundary = `--${crypto.randomUUID()}`
const body = messages.reduce((p: string, n: SingleMultipartMixedMessage) => {
return p + `\nContent-Type: ${n['Content-Type']}\n\n${n.body}\n${boundary}`
}, boundary)
const r = axios.post(catcher, body, {
headers: {
'Authorization': 'Bearer KEY',
'content-type': `multipart/mixed; boundary=${boundary.replace(/^--/, '')}`
}
})
expect(r).not.toBeNull();
})
and comparison of requests caught by caught between reference implementation [ request ] and our code [ axios ]
How to parse multipart mixed
Get boundary from content-type header
Add -- before it
Split body by this boundary
Any part split by double \n
Parse any pair of headers and data individually

Fetch gives back an Internal Server Error while Postman accepts it

In Postman I call a request to an API with success.
When I try this using fetch() in ReactJS it gives back an Internal Server Error (500)
My Fetch looks like:
const FetchData = async (url , request) => {
return await fetch(url, request)
.then(async function(res) {
if (res.ok)
console.log("OK: " + await res.json())
else
console.log("NOT OK: " + await res.text())
});
}
Request:
{
method: "POST",
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: {
...
}
}
Postman > body:
{
"value": {
"RequestType":1,
"Dependencies":[],
"Priority":1,
"RequestLocation":"some string",
"RequestJSON": "some string",
"NoCache":true,
"PostNow":true,
"Authentication": {
"Email":"string",
"Device": {
"Name":"string",
"UniqueDeviceId":"string",
"AppVersion":"string",
"AppType":int,
"Devicestatus":int
}
}
}
}
I'm 100% sure that both body's are equal to each other.
I cannot find out what the problem is. Do you guys see it?
fetch will send the body as is, in your case you are sending a JS object, not JSON data i.e.
body: { ... }
If the server is expects JSON data then you will need to convert your object to a JSON string i.e.
body: JSON.stringify({ ... })
P.S. it's worth noting that this has probably highlighted a lack of validation on your server-side for invalid requests, you might want to fix that.

Retrieve then POST a photo to a Foursquare Checkin with Axios

I'm trying to retrieve, then POST a JPEG image to Foursquare's https://api.foursquare.com/v2/photos/add endpoint using Axios in Node. I've tried a few methods with Axios (and Postman) but always receive the same error response of Missing file upload:
{
"meta": {
"code": 400,
"errorType": "other",
"errorDetail": "Missing file upload",
"requestId": "NNNNNNNNNNNNNNNNNNNNN" // not the true requestId
},
"notifications": [
{
"type": "notificationTray",
"item": {
"unreadCount": 0
}
}
],
"response": {}
}
The image is created using the Google Static Map API and retrieved with an Axios GET request:
const image = await axios.get(imageURL, {
responseType: "arraybuffer"
});
which is wrapped in an async function and successfully returns a buffer. The data is read into a Buffer and converted to a string:
const imageData = new Buffer(image, "binary").toString();
Here's an example imageData string. I've also tried converting the string to base64.
This string is then POSTed to the Foursquare endpoint:
const postPhoto = await axios.post(
"https://developer.foursquare.com/docs/api/photos/add?
checkinId=1234&
oauth_token=[TOKEN]&
v=YYYYMMDD",
imageData,
{
headers: { "Content-Type": "image/jpeg" }
}
);
where the checkinId, oauth_token and v params are all valid.
I've tried different Content-Type values, base64 encoding the imageData and several other solutions found in forums and here on SO (most are several years old), but nothing works. The response errorDetail always says Missing file upload.
The issue could be in how the POST request is structured, but I could also be requesting/handling the image data incorrectly. A 2nd (or 3rd, or 4th) set of eyes to check I'm putting this together would be super helpful.
Whew, I have finally solved this.
I was eventually able to get it working thru Postman which provided some hints. Here's the Postman code snippet using request:
var fs = require("fs");
var request = require("request");
var options = { method: 'POST',
url: 'https://api.foursquare.com/v2/photos/add',
qs:
{ checkinId: [MY CHECKING ID],
public: '1',
oauth_token: [MY OAUTH TOKEN],
v: [MY VERSION] },
headers:
{ 'postman-token': '8ce14473-b457-7f1a-eae2-ba384e99b983',
'cache-control': 'no-cache',
'content-type': 'multipart/form-data; boundary=---- WebKitFormBoundary7MA4YWxkTrZu0gW' },
formData:
{ file:
{ value: 'fs.createReadStream("testimage.jpg")',
options: {
filename: 'testimage.jpg',
contentType: null
}
}
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
The key part of this was fs.createReadStream(). The part I was missing before was to pass the image as a stream to the request.
Using this I was able to figure out the Axios request:
const axios = require("axios");
const querystring = require("qs");
const FormData = require("form-data");
const getImageStream = async function(url) {
return await axios
.get(url, {
responseType: "stream"
})
.then(response => response.data);
};
let form = new FormData();
form.append("file", getImageStream([IMAGE URL]));
const requestURL = "https://api.foursquare.com/v2/photos/add";
const requestParams = {
checkinId: [MY CHECKIN ID],
public: 1,
oauth_token: [MY OAUTH TOKEN],
v: [MY VERSION]
};
const requestConfig = {
headers: form.getHeaders()
};
try {
const postPhoto = await axios.post(
requestURL + "?" + querystring.stringify(requestParams),
form,
requestConfig
);
return postPhoto;
} catch (e) {
console.error(e.response);
}
And voila, the request succeeds and the image is posted to the Foursquare checkin.

Categories