I'm trying to load an image from a WMS into mapnik, but I'm getting an error Unhandled rejection Error: image_reader: can't determine type from input data. The code, stripped down, is
const request = require('request-promise');
const mapnik = require('mapnik');
request(`${wmsUrl}/GetMap`, {
qs: {
bbox: '-90,32,-89,33',
format: 'image/png',
height: 200,
layers: '5',
request: 'GetMap',
'srs(crs)': 'EPSG:4326,
styles: 'default',
version: '1.1',
width: 200,
},
}).then(res => {
const buffer = new Buffer(res);
return mapnik.Image.fromBytesSync(buffer); // This is the error line
});
I've run the request manually and it works, and I've inspected the buffer and it looks good (i.e. has 'PNG' at the start). I'm not sure what else to try.
In case anyone else encounters something similar to this, the problem is that request (or in this case request-promise) assumes that the response body should be a string and implicitly performs toString on it. To solve, the request should be
request(url, {
qs: { ... },
encoding: null,
}).then({ ... });
See more details here: https://github.com/request/request#requestoptions-callback
I solved my issue by specifying BOTH the responseType and the Content-Type header:
return axios.get(url, {
responseType: 'arraybuffer',
headers: {
'Content-Type': 'image/png',
},
});
Related
I have attempted to create a request in javascript, that has previously worked using python just fine.
the following is an accurate representation of the code I used to post the request with python:
url = 'https://website.com/api/e1'
header = {
'authorization': 'abcd1234'
}
payload = {
'content': "text",
}
r = requests.post(url, data=payload,headers=header )
This (above) works just fine in python.
now what I did in javascript is the following:
payload = {
"content": "this is text",
};
fetch("https://website.com/api/e1", {
method: "POST",
headers: {
"authorization":
"abcd1234",
},
body: JSON.stringify(payload),
});
but this is returning the error
400- Bad request
When using data parameters on python requests.post, the default Content-Type is application/x-www-form-urlencoded(I couldn't find it on the document, but I checked the request. If you know, please leave a comment).
To achieve the same result with fetch, you must do as follows.
const payload = {
'content': 'this is text',
};
fetch('https://website.com/api/e1', {
method: 'POST',
headers: {
'authorization': 'abcd1234',
},
body: new URLSearchParams(payload),
});
You don't need to do this body: JSON.stringify(payload), rather you can simply pass payload in body like this body:payload
I would like to a check for max-age so I remove items from cache when they get old, but I can't get my own header back for some reason.
export function cacheResponse(url, response) {
caches.open('my-cache').then(function(cache) {
cache.put(url, new Response(JSON.stringify(response), {
headers: {
'Cache-Control': 'max-age=1',
'Content-Type': 'application/json;charset=UTF-8'
}
}));
});
}
cacheResponse('/hello', {hello: "world"})
I can see this working in the Application tab in chrome and I can see those 2 headers in the preview, but when I pull the item back out the headers object is null.
cache.match(url).then(async function(object) {
console.log(object.headers) // null
var body = await object.clone().json(); // {hello: "world"}
})
The object looks like this
object: Response
body: ReadableStream
bodyUsed: false
headers: Headers
__proto__: Headers
ok: true
redirected: false
status: 200
statusText: ""
type: "default"
url: ""
Seems like I should be able to lookup the headers from calling match() no?
That should work; you should be able to call response.headers.get('cache-control') to retrieve the value (assuming this is a same-origin response).
Here's a snippet of code that I just tested which worked when run in the JS console:
async function test() {
const constructedResponse = new Response('test', {
headers: {'cache-control': 'max-age=1'}
});
const cache = await caches.open('test');
cache.put('/test', constructedResponse);
const matchedResponse = await cache.match('/test');
console.log(`cache-control: ${matchedResponse.headers.get('cache-control')}`);
}
I am hitting carrot2s api with:
const xml =
`<?xml version="1.0" encoding="UTF-8"?>
<searchresult>
<query>bob</query>
<document id="https://api.cognitive.microsoft.com/api/v7/#WebPages.0">
<title>Bob O's Family Fun Center | El Paso, TX</title>
<url>http://www.bing.com/cr?IG=29AD4AB87B7B438D8F2AA5967E17967DCID=24C5C22679EF67D1293BCE6078F66638rd=1h=AaGhCeGCFZPjz86DB6AZMIlM8b3VlbHiXWyUPsmFL_k=1r=http%3a%2f%2fbobosfun.com%2fp=DevEx.LB.1,5071.1</url>
<snippet>Bob-O’s is El Paso’s Premier Family Fun Center. Located on the Westside off Sunland Park Drive, Bob-O’s offers a variety of entertainment for the entire family.</snippet>
</document>
</searchresult>`
fetch(`carrot2server/dcs/rest`, {
method: 'POST',
body: {
'dcs.c2stream': xml,
'results': 100,
'dcs.algorithm': 'lingo',
'dcs.output.format': 'JSON'
}
})
.then(function(response) {
response.text().then(function(text) {
console.log(text);
})
}).catch(function(err) {
console.log(err)
});
If I run the same request in postman I get the expected results.
The error that I am receiving is:
HTTP Status 400 – Bad Request
Either dcs.source or a non-empty document list in dcs.c2stream must be
provided
The server cannot or will not process the request due to something
that is perceived to be a client error (e.g., malformed
request syntax, invalid request message framing, or deceptive request
routing).
This was fixed by setting the correct encodeURIComponent and adding the content type: application/x-www-form-urlencoded
const params = {
'dcs.c2stream': xml,
'results': 100,
'dcs.algorithm': 'lingo',
'dcs.output.format': 'JSON'
}
const searchParams = Object.keys(params).map((key) => {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
fetch('carrot2server/dcs/rest', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: searchParams
})
.then(function(response) {
response.text().then(function(text) {
console.log(text);
})
}).catch(function(err) {
console.log(err)
});
I have a form with multiple fileds, which one is a file input. I use axios to upload the file under a separate attribute:
axios.post(ENDPOINT,{
form: formData,
image: image
}, getAuthorizationHeader())
function getAuthorizationHeader() {
return {
headers: {
'Authorization': //...,
'Content-Type': undefined
}
};
}
formData is created like this:
let formData = new FormData();
formData.append('title', values.title);
formData.append('description', values.description);
formData.append('amount', values.amount);
And the image is:
Under the network tab of the Chrome Dev tool, When I look at the request, it looks like this:
As you can see in the screenshot, the file is empty? The CONTENT-TYPE is application/json which is not what I expected. I expected browser to detect the CONTENT-TYPE as multipart/form-data
What is wrong here?
First of all, image should be part of the formData:
formData.append('image', <stream-of-the-image>, 'test.png')
Secondly, formData should be the second parameter of axios.post:
axios.post(ENDPOINT, formData, getAuthorizationHeader())
Last but no least, you should merge formData.getHeaders():
function getAuthorizationHeader() {
return {
headers: Object.assign({
'Authorization': //...,
}, formData.getHeaders())
};
}
Sample code for your reference: https://github.com/tylerlong/ringcentral-js-concise/blob/master/test/fax.spec.js
We have a multi file upload requirement and the approach is below. I am sending all the requests as below and it works fine normally. However when tried with around 10 files with couple of them more than 10MB in Firefox only request gets rejected.enter image description here
(function (i) {
var formData = new FormData();
formData.append('file', $scope.files[i]);
$http.post('yourUrl', formData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(function () {
// ...
});
}(i);
"Request error:" Object { data: null, status: 0, headers: Xc/<(), config: Object, statusText: "" } angular.min.js:103:49
e/<() angular.min.js:103
.responseError() <myname>Service.js:59
f/<() angular.min.js:112
Pe/this.$get</l.prototype.$eval() angular.min.js:126
Pe/this.$get</l.prototype.$digest() angular.min.js:123
Pe/this.$get</l.prototype.$apply()
I spent lot of time but didnt get any solution.