Closed jgauna closed 9 years ago
Hey @jgauna, I use this plugin with CORS all the time so it definitely supports it :)
What response are you getting back from the api when this xhr returns?
I'm getting
XMLHttpRequest cannot load http://192.168.0.21:3000/api/syncImage. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 404.
And the call
Remote Address:192.168.0.21:3000
Request URL:http://192.168.0.21:3000/api/syncImage
Request Method:OPTIONS
Status Code:404 Not Found
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-419,es;q=0.8
Access-Control-Request-Headers:authorization, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:192.168.0.21:3000
Origin:null
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36
Response Headersview source
cache-control:no-cache
Connection:keep-alive
content-encoding:gzip
content-type:application/json; charset=utf-8
Date:Tue, 31 Mar 2015 14:26:53 GMT
Transfer-Encoding:chunked
vary:accept-encoding
The odd thing is that if do not use this in my ajax call it works.
server
auth: 'simple'
ajax call
xhr.setRequestHeader("Authorization", "Bearer 1234");
xhr.withCredentials = "true";
On the other side if the domain is the same it works great with authorization.
Any ideas?
Ok after looking into it in more details there seems to be two problems here.
server.route({
path: '/{p*}',
method: 'OPTIONS',
handler: function(req, reply){
console.log('test');
reply({method: 'options'});
},
config: {
auth: false,
cors: true
}
});
xhr.withCredentials = "true"
is causing the problem here too, I get the following error:
A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://127.0.0.1:8080' is therefore not allowed access.
in Chrome. I think this is used for basic auth so messing up the headers. After removing that line form the request everything worked for me. Really I'd advise using a library for your xhr's though as they abstract away having to deal with the different browser quirks around xhr's. Let me know how you get on!
I can't make it work yet. Here's my full code:
As it's right now I'm getting: XMLHttpRequest cannot load http://192.168.0.21:3000/api/syncImage. Invalid HTTP status code 401
Route code (Just know I'm using a boilerplate and maybe the hapi code looks odd but it's ok)
syncImage: {
handler: function(req, reply) {
console.log("UPLOADING ......");
server.methods.uploadImage(req, reply);
},
payload:{
maxBytes:209715200,
output:'stream',
parse: false
},
auth: 'simple',
cors: {
origin: ['*'],
credentials: true
},
id: 'syncImage'
}
And the client side:
var cvs = document.createElement('canvas');
cvs.width = compressed_img_obj.naturalWidth;
cvs.height = compressed_img_obj.naturalHeight;
var ctx = cvs.getContext("2d").drawImage(compressed_img_obj, 0, 0);
//ADD sendAsBinary compatibilty to older browsers
if (XMLHttpRequest.prototype.sendAsBinary === undefined) {
XMLHttpRequest.prototype.sendAsBinary = function(string) {
var bytes = Array.prototype.map.call(string, function(c) {
return c.charCodeAt(0) & 0xff;
});
this.send(new Uint8Array(bytes).buffer);
};
}
var type = "image/jpeg";
if(filename.substr(-4)==".png"){
type = "image/png";
}
var data = cvs.toDataURL(type);
data = data.replace('data:' + type + ';base64,', '');
var xhr = new XMLHttpRequest();
xhr.open('OPTIONS', 'http://192.168.0.21:3000/api/syncImage', true);
xhr.setRequestHeader("Authorization", "Bearer 1234");
xhr.withCredentials = true;
var boundary = 'someboundary';
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
// Set custom request headers if customHeaders parameter is provided
if (customHeaders && typeof customHeaders === "object") {
for (var headerKey in customHeaders){
xhr.setRequestHeader(headerKey, customHeaders[headerKey]);
}
}
// If a duringCallback function is set as a parameter, call that to notify about the upload progress
if (duringCallback && duringCallback instanceof Function) {
xhr.onprogress = function (evt) {
if (evt.lengthComputable) {
return (evt.loaded / evt.total)*100;
}
};
}
xhr.sendAsBinary(['--' + boundary, 'Content-Disposition: form-data; name="' + file_input_name + '"; filename="' + filename + '"', 'Content-Type: ' + type, '', atob(data), '--' + boundary + '--'].join('\r\n'));
xhr.onreadystatechange = function() {
if (this.readyState == 4){
if (this.status == 200) {
successCallback(this.responseText);
}else if (this.status >= 400) {
if (errorCallback && errorCallback instanceof Function) {
errorCallback(this.responseText);
}
}
}
};
Extra info:
http://192.168.0.21:3000/api/syncImage
route has OPTIONS
as methodnull
because the script is a local fileI really appreciate a lot your help !
Hey @jgauna I'm on holiday at the moment sorry for delay on this - will be back on the 18th if I don't get to it before then!!
Thanks for the answer @johnbrett. I was able to fix it using:
// Create a new server
var server = new Hapi.Server({
connections: {
routes: {
cors: true
}
}
});
Now, all routes will have cors available and working with Authorization headers :bowtie:
Have a nice holidays!
Hey @jgauna, glad you got sorted on this. Thanks for posting the solution also!
Here's my route:
And in the client:
Am I missing something?
Regards