Ajax file upload in node.js - ajax

Want to upload a file using ajax for this using this uploader
http://valums.com/ajax-upload/
and in node.js write this code which is working with normal file upload without ajax .
console.log("request " + sys.inspect(req.headers));
req.on('data', function(chunk) {
console.log("Received body data:");
// console.log(chunk.toString());
});
var form = new formidable.IncomingForm();
form.parse(req, function(err,fields, files) {
console.log('in if condition'+sys.inspect({fields: fields, files: files}));
fs.writeFile("upload/"+files.upload.name, files.upload,'utf8', function (err) {
if (err) throw err;
console.log('It\'s saved!');
client.putFile("upload/"+files.upload.name, files.upload.name, function(err, res){
if (err) throw err;
if (200 == res.statusCode) {
console.log('saved to s3');
httpres.writeHead(200, {'content-type': 'text/plain'});
httpres.write('received 1upload:\n\n');
httpres.end();
}
});
});
});
But this is giving error ?
request { host: 'myhost:8001',
'user-agent': 'Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'accept-language': 'en-us,en;q=0.5',
'accept-encoding': 'gzip, deflate',
'accept-charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'keep-alive': '115',
connection: 'keep-alive',
origin: 'http://myhost',
'access-control-request-method': 'POST',
'access-control-request-headers': 'content-type' }
events.js:45
throw arguments[1]; // Unhandled 'error' event
^
Error: bad content-type header, no content-type
at IncomingForm._parseContentType (/usr/local/lib/node/.npm/formidable/1.0.0/package/lib/formidable/incoming_form.js:196:17)
at IncomingForm.writeHeaders (/usr/local/lib/node/.npm/formidable/1.0.0/package/lib/formidable/incoming_form.js:109:8)
at IncomingForm.parse (/usr/local/lib/node/.npm/formidable/1.0.0/package/lib/formidable/incoming_form.js:65:8)
at Server.<anonymous> (/home/myfolder/myfolder/newcontentserver.js:29:18)
at Server.emit (events.js:67:17)
at HTTPParser.onIncoming (http.js:1108:12)
at HTTPParser.onHeadersComplete (http.js:108:31)
at Socket.ondata (http.js:1007:22)
at Socket._onReadable (net.js:678:27)
at IOWatcher.onReadable [as callback] (net.js:177:10)
I think problem is the content-type is not set in the headers By ajax file upload .thats why this error is coming how can i set the header in this uploader , or how can i make a file in node.js server by incoming data.
As it is using the xhr so i think i can't use the formidable.incomingform() what should i use?

Looking at the latest fileuploader.js source code on github he does set the content type
xhr.setRequestHeader("Content-Type", "application/octet-stream");
I believe your problem is elsewhere.

Related

How to override cy.request() and set up bearer authorization header globally?

I need to set the authorization bearer header for cy.request() globally to avoid setting it up multiple times.
Here I found some potential way to do it.
So in my support/commands.ts I have:
Cypress.Commands.overwrite('request', (originalFn, ...options) => {
const optionsObject = options[0];
if (optionsObject === Object(optionsObject)) {
optionsObject.headers = {
authorization: `Bearer ${Cypress.env('authorizationToken')}`,
...optionsObject.headers,
};
return originalFn(optionsObject);
}
return originalFn(...options);
});
And in the test I have:
cy.request({
method: 'POST',
url: '/someEndpoint',
body: someBody
}).then(response => {
expect(response.status).eq(200);
return response.body;
});
And unfortunately, I get 401: Unauthorized error and it looks like the authorization bearer token was not added to headers:
What do I do wrong here? I use Cypress v 10.10.0

Fetch request headers vs. Postman headers

Using Postman I'm able to do the following call:
GET https://tickets.ramdom.com/api/events/95
Request Headers
Host: tickets.ramdom.com
Cookie: OptanonConsent=isIABGlobal=false
Cache-Control: no-cache
Postman-Token: db42ad48-62f1-4e3f-8903-66002116e8a3
The call works fine. Now I want to reproduce the same call using fetch and Firefox console.
So I create the following piece of code:
const opts = {
headers: {
Host: 'tickets.ramdom.com',
Cookie: 'OptanonConsent=isIABGlobal=false'
}
};
fetch('hhttps://tickets.ramdom.com/api/events/95', opts)
.then((response) => {
alert(response)
})
.catch((error) => {
alert(error)
});
But I always get the following error:
TypeError: NetworkError when attempting to fetch resource.
Do you know what I'm doing wrong?
Thanks

Getting error when returning list from rest service admin-on-rest

I'm getting the following error on my first admin component.
uncaught at handleFetch TypeError: newRecords.reduce is not a function
When I attempt to query my rest-api. I'm using the majority of the supplied simple rest client with some additional security headers thrown in.
My response from my API is:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Content-Range: Account 0-0/1
Server: Kestrel
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Range
Request-Context: appId=cid-v1:9f32da6c-a0dd-445f-b59f-d5d01ee6c462
X-AA-Request-ID: ad76be2b-0a29-4179-8fab-6ac0b83e411b
X-SourceFiles: =?UTF-8?B?RTpcRGV2XEFBSHViXEFBLkh1Yi5TZXR0aW5ncy5TZXJ2aWNlXEFBLkh1Yi5TZXR0aW5ncy5TZXJ2aWNlXGFwaVx2MVxhY2NvdW50?=
X-Powered-By: ASP.NET
Date: Tue, 15 Aug 2017 02:56:56 GMT
The body of the response has:
{"data":[{"changeManagements":[],"serviceProfiles":[],"id":1,"login":"cuken","permissionLevel":9001,"note":"This is a dev test user"}],"totalItems":1}
EDIT
Here is the fetch.js file I modified from the simple rest client example:
import HttpError from './HttpError';
export const fetchJson = (url, options = {}) => {
const requestHeaders = options.headers || new Headers({
Accept: 'application/json',
'X-AA-ClientName': 'fc5f3712-64fc-4ca4-9e5f-d4b6edeb46d4',
'X-AA-ApiKey': '80b4ccbf-a741-42ad-aacc-50c4309de8e6',
});
if (!(options && options.body && options.body instanceof FormData)) {
requestHeaders.set('Content-Type', 'application/json');
}
if (options.user && options.user.authenticated && options.user.token) {
requestHeaders.set('Authorization', options.user.token);
}
return fetch(url, { ...options, headers: requestHeaders })
.then(response => response.text().then(text => ({
status: response.status,
statusText: response.statusText,
headers: response.headers,
body: text,
})))
.then(({ status, statusText, headers, body }) => {
let json;
try {
json = JSON.parse(body);
} catch (e) {
// not json, no big deal
}
if (status < 200 || status >= 300) {
return Promise.reject(new HttpError((json && json.message) || statusText, status));
}
return { status, headers, body, json };
});
};
export const queryParameters = data => Object.keys(data)
.map(key => [key, data[key]].map(encodeURIComponent).join('='))
.join('&');
The simple.js file is an exact copy from the repo.
What did I do wrong?
You need a dedicated auth client to handle the auth types and shoot the appropriate actions
https://marmelab.com/admin-on-rest/Admin.html#authclient
That's because your API response is not what the simpleRestClient expects:
It should only contains
[{"changeManagements":[],"serviceProfiles":[],"id":1,"login":"cuken","permissionLevel":9001,"note":"This is a dev test user"}]
No data nor totalItems keys. As stated in the documentation:
The simple REST client expects the API to include a Content-Range header in the response to GET_LIST calls. The value must be the total number of resources in the collection. This allows admin-on-rest to know how many pages of resources there are in total, and build the pagination controls.

NodeJS HTTP GET returns empty body

Here's a NodeJS code snippet I'm debugging. The url is correct, and a GET request to it with Postman returns a 200 OK with the following headers. The response body is a valid JSON string.
Headers (arrows represent column divisors)
Accept-Ranges →bytes
Age →0
Cache-Control →max-age=300
Connection →keep-alive
Content-Encoding →gzip
Content-Length →255
Content-Type →application/json
Date →Tue, 24 Jan 2017 22:37:28 GMT
Expires →Tue, 24 Jan 2017 17:47:43 GMT
Last-Modified →Tue, 24 Jan 2017 01:03:08 GMT
Server →nginx
Vary →Accept-Encoding
Via →1.1 varnish
X-Cache →HIT
X-Cache-Hits →1
X-Served-By →cache-yul8926-YUL
X-Timer →S1485297448.259768,VS0,VE89
The problem:
I've discovered that res.on('data', function(chunk) { never gets called which causes body to remain empty.
When res.on('end', function() { is called body still has length = 0. Any ideas why the data callback is not getting called?
http.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
var data = JSON.parse(body);
cb(data, undefined);
});
}).on('error', function(err) {
console.log("Something went wrong");
console.log(err);
});
Also worth nothing, cb is a callback function defined outside of this snippet.
After the lovely advice from jfriend00 I discovered that res.statusCode was 301 (Moved Permanently). Seems that the website was redirecting to the same URL but with https protocol instead of http.
When testing the REST API with Postman it did not mention the fact the request was redirected. Postman displayed a 200 OK response (???) According to the Postman Docs it will default to following redirects silently.
The solution:
I replaced all instances of http with https and it worked great.
https.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
var data = JSON.parse(body);
cb(data, undefined);
});
}).on('error', function(err) {
console.log("Something went wrong");
console.log(err);
});

IE striping headers from HTTP POST request to S3

I'm doing straight-to-S3 multipart file upload via AJAX. Everything works fine under all browsers but IE.
S3 requires an Authorization HTTP header in each POST request which contains the signature of the file slice being uploaded.
It appears IE strips out this header from the request, yielding a 403 response.
What's more funny is that IE does not strip another custom S3 header: x-amz-date.
Any idea how I can force the 'Authorization' header in?
As requested, here is my code :
initiateUpload: function() {
var response = this.sign({method:'POST', path: this.key + '?uploads'});
this.request({
method: 'POST',
url: response.url,
headers: {
'x-amz-date': response.date,
'Authorization': response.signature
},
onLoad: this.uploadParts.bind(this)
});
},
request: function(params){
var xhr = new XMLHttpRequest();
if (params.onLoad) xhr.addEventListener("load", params.onLoad, false);
if (params.onUploadStart) xhr.upload.onloadstart = params.onUploadStart;
if (params.onUploadProgress) xhr.upload.onprogress = params.onUploadProgress;
xhr.open(params.method, params.url, true);
for (h in params.headers)
xhr.setRequestHeader(h, params.headers[h]);
xhr.send(params.body);
},

Resources