I've problem with settings header. My js script
var invocation = new XMLHttpRequest();
var url = 'http://example.com/api/auth';
var handler = [];
if(invocation) {
invocation.open('GET', url, true);
invocation.setRequestHeader('X-PINGOTHER', "DDD");
invocation.setRequestHeader('Access-Control-Allow-Origin', "http://localhost");
invocation.setRequestHeader('Access-Control-Request-Headers', true);
invocation.onreadystatechange = handler;
invocation.send();
}
Header from firebug:
OPTIONS /api/auth HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0 FirePHP/0.7.4
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
Origin: http://localhost
Access-Control-Request-Method: GET
Access-Control-Request-Headers: access-control-allow-origin,x-pingother
x-insight: activate
Connection: keep-alive
As you can see it always adds to the Access-Control-Request-Headers as value, and sets OPTIONS no GET. Any idea?
You should use the $http that comes with AngularJS, much better:
$http.defaults.useXDomain = true; //enable cors
$http({
method: 'GET',
url: 'http://example.com/api/auth',
headers: {'X-PINGOTHER': 'DDD'}
});
All right, it's working, but not with GET.
How it's should be:
$http({
method: "GET",
url: "http://example.com/api/auth"
}).success(function(data) {
$scope.user = data;
}).error(function(data) {
console.log("error");
});
Working example :
$http.jsonp('http://example.com/api/auth?&callback=JSON_CALLBACK')
.success(function(data){
console.log(data);
}).error (function(data){
alert("eerrror");
});
It works only with JSONP.
Related
im using an ajax get request to get data from the server (a spotify playlist structure, to be displayed for the user. But I'm having some trouble with transmitting. This issue is only prevelent when using the external ip (and not with localhost)
The data being received correctly on localhost:
with headers:
Request URL: http://www.localhost:8080/spotify/ajax/requestSongs
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
Content-Length: 821946
Content-Type: application/json; charset=utf-8
Date: Tue, 14 Apr 2020 19:18:51 GMT
ETag: W/"c8aba-7NdUbhReuN0XXnw3DPVSyrNAS38"
X-Powered-By: Express
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Cookie: connect.sid=s%3A0yZXFKy7MgsfbY_OX5yanp5HKlvdSGKY.8BaJrUmEGn9z9ohyRTtkXBCTj6wxiDDoaLNFS8vEdl8
Host: www.localhost:8080
If-None-Match: W/"c8aba-7NdUbhReuN0XXnw3DPVSyrNAS38"
Referer: http://www.localhost:8080/spotify/edit?playlist=5LDRNl7lGrxm7mx2RVggVC
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
The data being incorrectly received on external ip:
with headers:
Request URL: http://86.90.233.152:8080/spotify/ajax/requestSongs
Request Method: GET
Status Code: 200 OK
Remote Address: MYIP:8080
Referrer Policy: no-referrer-when-downgrade
Connection: keep-alive
Content-Length: 821946
Content-Type: application/json; charset=utf-8
Date: Tue, 14 Apr 2020 19:03:00 GMT
ETag: W/"c8aba-7NdUbhReuN0XXnw3DPVSyrNAS38"
X-Powered-By: Express
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Cookie: connect.sid=s%3AlGbD5iWpq9sJlLCFvBsj20RkR9_gZrEr.D9rOpXr5M6FfHnUe7DUx0xzLybQhsGsLIuYsys0FrP4
Host: 86.90.233.152:8080
Referer: http://MYIP:8080/spotify/edit?playlist=5LDRNl7lGrxm7mx2RVggVC
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
The ajax response doesn't change after the second XMLhttp reply.
Furthermore, to try and find the issue I log every response coming into ajax and the console is:
clientscript.js:8 XMLHttpRequest {readyState: 1, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
clientscript.js:8 XMLHttpRequest {readyState: 2, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
clientscript.js:8 XMLHttpRequest {readyState: 3, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
clientscript.js:8 XMLHttpRequest {readyState: 3, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
SOURCE:
Server side replier
router.get("/ajax/requestSongs", function(req,res, next)
{
if(req.session.lastPlaylist)
{
localPlaylists[res.locals.sessionId].getSortedGenres((sortedGenres) => localPlaylists[res.locals.sessionId].getPlaylist( (playlist) =>
{
var data={sortedGenres : sortedGenres, playlist : playlist}
console.log(data);
res.send(data);
}));
}
});
Client side receiver:
function getData(suburl, callback)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
//console.log(this.responseText);
console.log(this)
if (this.readyState == 4 && this.status == 200)
{
console.log(this.responseText);
callback(this.responseText);
}
};
xhttp.open("GET", pathPrefix+"/ajax/"+suburl, true);
xhttp.send();
}
An example of how data is cut off (the ....... is correct data):
........"art rock","blues rock","classic rock","hard rock","metal","psychedelic rock","rock","soft rock"]},{"artists":[{"external_urls":{"spotify":"https://open.s
Because it only makes a difference when you're on an external link and the data is large (not huge, but not small either), I suspect that there's some sort of problem with the transmission, perhaps some sort of internal buffer overflow problem. I was under the impression that res.send() is supposed to just "handle that for you", but apparently that is not the case.
I would first add an error handler on the output stream and see if it logs anything:
router.get("/ajax/requestSongs", function(req, res, next)
{
if(req.session.lastPlaylist)
{
localPlaylists[res.locals.sessionId].getSortedGenres((sortedGenres) => localPlaylists[res.locals.sessionId].getPlaylist( (playlist) =>
{
var data={sortedGenres : sortedGenres, playlist : playlist}
console.log(data);
// log any errors on the response stream
res.on('error', function(err) {
console.log(err);
});
res.send(data);
}));
}
});
Then, my theory of some sort of buffer overflow would suggest that you need to implement flow control upon sending of the data. I thought res.send() was supposed to do that for you, but you can implement it yourself like this and see if it solves the problem:
router.get("/ajax/requestSongs", function(req, res, next) {
if(req.session.lastPlaylist) {
localPlaylists[res.locals.sessionId].getSortedGenres((sortedGenres) => localPlaylists[res.locals.sessionId].getPlaylist( (playlist) => {
res.type("application/json");
res.status(200);
const data = JSON.stringify({sortedGenres : sortedGenres, playlist : playlist});
const chunkSize = 1024 * 10; // send in 10k chunks
let pos = 0, chunk;
function sendNextChunk() {
if (pos < data.length) {
chunk = data.substr(pos, chunkSize);
pos += chunkSize;
let flushed = res.write(chunk);
if (!flushed) {
// need to wait for drain event before sending more
res.once('drain', sendNextChunk);
} else {
// send more without stack build-up
setImmediate(sendNextChunk);
}
} else {
// finish the response
res.end();
}
}
// log any write errors on the response
res.on('error', function(err) {
console.log(err);
});
// start the sending sequence
sendNextChunk();
}));
} else {
// have to send something here when no playlist
res.send("No previously established playlist");
}
});
I want to use the size and data of my POST request. I was doing some research and found out about the Content-Length header of a request, but I can't find it in my axios request headers.
I tried using interceptors, like that :
axios.interceptors.request.use(
config => {
console.log('config', config.headers);
if (config.url != `${API_URL}/login`)
config.headers.Authorization = 'Bearer ' + getAccessToken();
return config;
},
error => {
return Promise.reject(error);
}
);
And here is the response that I get:
Authorization: "Bearer [...access_token]"
Content-Type: "multipart/form-data"
common:
Accept: "application/json, text/plain, */*"
X-CSRF-TOKEN: "..."
X-Requested-With: "XMLHttpRequest"
__proto__: Object
delete: {}
get: {}
head: {}
patch: {Content-Type: "application/x-www-form-urlencoded"}
post: {Content-Type: "application/x-www-form-urlencoded"}
put: {Content-Type: "application/x-www-form-urlencoded"}
But in in Chrome this is what is shown:
Accept: application/json, text/plain
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ro;q=0.8,la;q=0.7
Authorization: Bearer [...access_token]
Connection: keep-alive
Content-Length: 5266672 <---- this is what I need
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGMzak87LIZH05nme
Cookie: XSRF-TOKEN= ...
Host: ...
Origin: ...
Referer: ...
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
X-CSRF-TOKEN: ...
X-Requested-With: XMLHttpRequest
X-XSRF-TOKEN: ...
Is there any way to make axios give me the content-length header? If not, is there any way to access it from anywhere else?
content-length will auto add by http adapter.
This question already has answers here:
Trying to use fetch and pass in mode: no-cors
(9 answers)
Closed 3 years ago.
I try to create a Header for a following fetch() like this
var myheaders = new Headers(
{ "Accept": "application/json",
"Content-Type": "application/json; charset=UTF-8"
});
let b = JSON.stringify ({ "cmd2" : "ytdl", "url" : "x"});
let params =
{ headers : myheaders,
body : b,
method : "POST",
mode : "no-cors"
};
let response = await fetch("http://127.0.0.1:5000/ytdl",params);
....
If I print the headers in the receiving Server (Flask) I get:
Host: 127.0.0.1:5000
Connection: keep-alive
Content-Length: 67
Accept: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Sec-Fetch-Mode: no-cors
Content-Type: text/plain;charset=UTF-8
Origin: chrome-extension://mnihgjnpmkpgeichhdfhejagbefjpnnb
Sec-Fetch-Site: cross-site
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Any Idea, what I´m doing wrong?
I didn't understand what is the reason but when you call without mode: 'no-cors' content type is:
let params = {
headers : myheaders,
body : b,
method : "POST",
mode : "cors"
};
response = await fetch("http://127.0.0.1:5000/", params);
The output of the flask request.headers:
...
Accept: application/json
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Sec-Fetch-Mode: cors
Content-Type: application/json; charset=UTF-8
...
i want to upload image using Angularjs anyone know how do this..REST API wants
Content-Type:multipart/form-data
www.abc.com/images/id
Request Body
{
// --Boundary_1_1626119499_1392398808202
// Content-Type: image/png
// Content-Disposition: form-data; filename="ducky.png"; modification-date="Wed, 05 Nov 2016 19:53:17 GMT"; size=713915; name="upload_image"
// {binary data truncated for display}
}
my Question is how to upload image file using above rest API, how to assign $scope.tempObject = my Upload image Path
$scope.UploadImage = function () {
var config = {headers: {
'Content-Type': 'multipart/form-data'
}
}
$http.post(properties.customerUploadImage_path + "/"+checkprofile,$scope.tempObject,config).success(function (response) {
Console.log('Uploaded');
});
}
I think you don't use $http the right way.
You can use the headers attribute of the $http service, like this :
$scope.UploadImage = function () {
var config = {
headers: {
'Content-Type': 'multipart/form-data',
}
};
$http({
method: 'POST',
url: properties.customerUploadImage_path + "/" + checkprofile,
data: $scope.tempObject,
config: config,
}).success(function (response) {
console.log('Uploaded');
});
};
I suggest you to take a look at the documentation.
Configure the headers with "Content-Type": undefined and use the FormData API:
var config = { headers: {
"Content-Type": undefined,
}
};
vm.upload = function() {
var formData = new $window.FormData();
formData.append("file-0", vm.files[0]);
$http.post(url, formData, config).
then(function(response) {
vm.result = "SUCCESS";
}).catch(function(response) {
vm.result = "ERROR "+response.status;
});
};
Normally the AngularJS $http service uses Content-Type: application/json. By setting Content-Type: undefined, the framework will omit the Content-Type header and the browser will use its default content type which is multipart/form-data for FormData objects.
Request Header
POST /post HTTP/1.1
Host: httpbin.org
Connection: keep-alive
Content-Length: 388298
Accept: application/json, text/plain, */*
Origin: https://run.plnkr.co
User-Agent: Mozilla/5.0 Chrome/55.0.2883.54 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9lBDT4yoh8lKWtIH
Referer: https://run.plnkr.co/cW228poRVzWs67bT/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Request Payload
------WebKitFormBoundary9lBDT4yoh8lKWtIH
Content-Disposition: form-data; name="file-0"; filename="Crop.jpg"
Content-Type: image/jpeg
------WebKitFormBoundary9lBDT4yoh8lKWtIH--
The DEMO on PLNKR.
For more information see,
AngularJS $http Service API Reference -- Setting HTTP Headers
MDN Documents -- FormData API
I want to send a request from a dummy webpage to a web app (deployed on a server in the same sub net). The thing is that I can't use jQuery.
Only JS (doesn't work):
var $token;
var username = "user1";
var password = "123456";
var url = "http://192.168.110.35:8080/wwdf/api/login";
var data = {"username": username, "password": password};
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.onreadystatechange = function(){
if (xhr.readyState == 4 && xhr.status == 200) {
$token = xhr.responseText.access_token;
} else {
console.log("Error: readyState = " + xhr.readyState + " | Status " + xhr.status);
}
};
xhr.send(JSON.stringify(data));
JQuery (works):
$.ajax({
method: 'POST',
url: url,
contentType: 'application/json',
username: username,
password: password,
data: JSON.stringify(data),
headers: {
'Accept': 'application/json',
'Content-Type': 'text/plain'
},
success: function (response) {
token = response.access_token;
$("#btn").prop('disabled', true);
}
});
Error:
XMLHttpRequest cannot load http://192.168.110.35:8080/wwdf/api/login. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
Network monitoring:
Response
Response Headers
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:accept, content-type, x-auth-token
Access-Control-Allow-Methods:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Content-Length:0
Date:Mon, 29 Feb 2016 15:59:29 GMT
Server:Apache-Coyote/1.1
Request Headers
Request
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, authorization, content-type
Access-Control-Request-Method:POST
Cache-Control:max-age=0
Connection:keep-alive
Host:192.168.110.35:8080
Origin:http://192.168.12.69
Referer:http://192.168.12.69/...
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
I don't know what I'm doing wrong, please help !
You need to configure your server to respond with authorization in the Access-Control-Allow-Headers header. Right now, that header is only set to accept, content-type, x-auth-token by your server. Or you need to remove the Authorization header from your JS example. In the JS example you set it, but in JQuery you don't. That's why you are getting different results.