The response text of Symfony StreamedResponse gets concatenated when using AJAX XMLHttpRequest - javascript

I have the controller below which returns Line 1 (as response) as soon as the endpoint is called. Two seconds later it returns Line 2. This is fine when I directly access URL http://ajax.dev/app_dev.php/v2 so this proves that the endpoint works as expected.
/**
* #Method({"GET"})
* #Route("/v2", name="default_v2")
*
* #return Response
*/
public function v2Action()
{
$response = new StreamedResponse();
$response->setCallback(function () {
echo 'Line 1';
ob_flush();
flush();
sleep(2);
echo 'Line 2';
ob_flush();
flush();
});
return $response;
}
When I use AJAX to call the same endpoint, the first response is fine which is response: "Line 1". However, the second one is response: "Line 1Line2" so it is combined. What should I do in order to get response: "Line2" as the second response? See console log below.
XMLHttpRequest { onreadystatechange: xhr.onreadystatechange(), readyState: 3,
timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload,
responseURL: "http://ajax.dev/app_dev.php/v2", status: 200,
statusText: "OK", responseType: "", response: "Line 1" }
XMLHttpRequest { onreadystatechange: xhr.onreadystatechange(), readyState: 3,
timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload,
responseURL: "http://ajax.dev/app_dev.php/v2", status: 200,
statusText: "OK", responseType: "", response: "Line 1Line2" }
Complete
This is the AJAX I am using.
$(document).ready(function () {
$('button').click(function () {
xhr = new XMLHttpRequest();
xhr.open("GET", 'http://ajax.dev/app_dev.php/v2', true);
xhr.onprogress = function(e) {
console.log(e.currentTarget);
};
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
console.log("Complete");
}
};
xhr.send();
});
});

This can only be a temporary solution for now because every single response adds up and become a massive response rather than having a clean response.
e.g.
Response 1: Hello
Response 2: World
Response 3: Bye
XMLHttpRequest e.currentTarget property would contain:
Hello
HelloWorld
HelloWorldBye
The responseText property of XMLHttpRequest always contains the content that's been flushed out of the server, even when the connection's still open. So the browser can run a periodic check, e.g. to see if its length has changed.
For the time being I'll use code below but if I can find a better solution, I'll post it.
<script>
$(document).ready(function () {
$('button').click(function () {
xhr = new XMLHttpRequest();
xhr.open('GET', 'http://ajax.dev/app_dev.php/v2', true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onprogress = function(e) {
var response = e.currentTarget.response;
var output = typeof lastResponseLength === typeof undefined
? response
: response.substring(lastResponseLength);
lastResponseLength = response.length;
console.log(output);
};
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
console.log('Complete');
}
};
xhr.send();
});
});
</script>

Related

how to call a service using ajax javascript?

I'm learning programing, could you explain me how to call a service using ajax javascript?
Service information:
Service type: REST
Basic authentication
Estructure: Application/JSON
Url: https://osb.urosario.edu.co/uxxi-URO/WsFotografias/proxy/AdministradorFotografiasJsonPS/fotos/consultar
User: Admi
Password: admi
Parameter JSON example: {"identificacion":["98122811999"]}
I've tested this service in postman
Service answer:
{
"respuesta": [
{
"estado": "Correcto.",
"identificacion": "98122811999",
"imagen": "return string Base 64 format"
}
]
}
Using JQuery :
$.ajax({
type: 'POST',
url: 'https://osb.urosario.edu.co/uxxi-URO/WsFotografias/proxy/AdministradorFotografiasJsonPS/fotos/consultar',
dataType: 'json',
data:{"identificacion":["98122811999"]}
contentType: "application/json"
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', make_base_auth("admi", "admi"));
},
success: function (data,status) {
//do what you want with the data after success
//in this example the response will be promoted in the browser console
console.log(data);
});
});
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return 'Basic ' + hash;
}
You can call your above RestEndpoint using below:
xmlhttp.open("POST", "/EndpointURI", true);
xmlhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
//Use parse() method to convert JSON string to JSON object
var responseJsonObj = JSON.parse(this.responseText);
//use response
}
};
var jsonData = {"name" : "yourData"};
xmlhttp.send( JSON.stringify( jsonData ) );
For Authentication use this:
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://EndPointURI", true);
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", 'Basic ' + btoa('userName:password'));
xhr.onload = function () {
console.log(xhr.responseText);
};
xhr.send();
For authentication part, use JQuery then it will easy for the implementation and as well for understanding. as now aday no body use basic xmlhttp for calling api in javascript, last time i used was a 2003 developed application.

Retrieving response payload elements from XMLHttpRequest

I'm sending a JSON request (an applicative login but the kind of request doesn't matter) to a server with the following function:
function login() {
var payload = {
"api_key" : "", "cmd" : "login",
"params" : {}
}
payload["params"]["username"] = document.getElementById("uname").value
payload["params"]["password"] = document.getElementById("passwd").value
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:4000/api", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.setRequestHeader("Accept", "application/json");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
resp = JSON.parse(xhr.responseText);
console.log("resp.status=" + resp.status);
console.log("resp.[\"status\"]=" + resp["status"]);
}
}
xhr.send(JSON.stringify(payload));
}
I'm actually getting the correct reply in the responseText field. For example, if the credentials are wrong, I get
{
"status": "ko",
"errors": [
{
"cmd": "login",
"long": "Login error : 'user-20' has no access to the system",
"short": "login_error"
}
]
}
If the credentials are OK I get
{
"status": "ok",
... some additional data
}
Yet, I can't manage to get the status field : resp.status or resp["status"] are always undefined. Same if the call is done in asynchroneous mode (xhr.open("POST", "http://localhost:4000/api", false);) or if I don't JSON.parse() the reply, ie: resp = xhr.responseText;.
Update - 2017.09.06
I finally found a way to get it working, but I don't quite understand why it is so. I actually changed
resp = JSON.parse(xhr.responseText);
into
resp = JSON.parse(JSON.parse(xhr.responseText));
To figure this out, I printed typeof(xhr.responseText) which is a sting. Actually typeof(JSON.parse(xhr.responseText)) is also a string and this is why it has no fields like status. Eventually, parsing xhr.responseText twice gives an object from which I actually can retrieve my data.
If somebody has a clue about what is happening, I would be interested... I don't know if this is related, but the app server that is sending the JSON is the latest version of Elixir/Phoenix, ie, 1.5/1.3 and JSON encoding/decoding is done with poison.
This is because you have assigned the resp variable to responseText
resp = JSON.parse(xhr.responseText);
To get the response code
respCode = xhr.status
Or if you want both in the same resp variable you could do
resp = {
responseText: xhr.responseText,
status: xhr.status
}
Then you can access them as resp.responseText and resp.status

Unable to send cross-domain request in `Firefox` extension

I am trying to access cross-domain data by using jsonp or XMLHttpRequest with GET method. My Code:
XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com/ajax.php?code=BSE", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
alert(xhr.responseText);
}
xhr.send();
JsonP
$.ajax({
type: 'GET',
url: "http://example.com/ajax.php?code=BSE",
dataType: "jsonp",
jsonpCallback: "jsonp_callback",
crossDomain: true,
success: function(res){
console.log(res);
}
});
Both methods having same behavior. Whenever i am sending request its just keep loading (even i am not sure its sending request or not) and do nothing.
And my php code:
PHP Code:
header('content-type: application/json; charset=utf-8');
$dts=array('value'=>'123');
echo $_GET['jsonp_callback'] . '('.json_encode($dts).')';
The XMLHttpRequest will work just fine, no need for jsonp. In your manifest.json, make sure you request permissions for the domain you are posting to -- Chrome doesn't require permissions for XHR, but Firefox does. This error manifests in Firefox as a http code 404 in the XHR, but no activity in the network panel. If you get a http code 0, you have CORS or mixed content security issues as well.
{
"manifest_version": 2,
"name": "web extension",
"version": "1",
"permissions": [
"http://example.com/"
],
"content_scripts": [
{
// ...
}
]
}
Try using new XDomainRequest() in your xhr request. XDomainRequest is an implementation of HTTP access control (CORS).
var createCORSRequest = function(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Most browsers.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// IE8 & IE9
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
};
var url = 'http://example.com/ajax.php?code=BSE';
var method = 'GET';
var xhr = createCORSRequest(method, url);
xhr.onload = function() {
// Success code goes here.
};
xhr.onerror = function() {
// Error code goes here.
};
xhr.setRequestHeader('content-type', 'application/json; charset=utf-8');
xhr.send();

jQuery vs. JavaScript ajax 'POST' functions

This jQuery code is working:
$.ajax({
type: "POST",
url: "file.php",
data: { json: json },
complete: function (data) {
var result = data.responseText;
console.log(result); // logs 'echo' from PHP file
}
});
This JavaScript code is still not working:
var xhr = new XMLHttpRequest();
xhr.open("POST", "file.php", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var result = xhr.responseText;
console.log(result); // supposed to log 'echo' from PHP file
}
}
xhr.send(JSON.stringify(json));
Aren't these two approaches equivalent, or am I missing something?
Suppose 'file.php' looks something like this:
if(isset($_POST['json'])){
$obj = json_decode($_POST['json']);
//some php operation
// echo $obj keys and values
}
data : { json: json }
gets serialized to '{ "json": {data} }'
JSON.stringify(json)
gets serialized to '{data}' and there is no "json" key
add your javascript object to a parent wrapper object with a "json" key
JSON.stringify({ json: json });

Getting a JSON file using XMLHttpRequest() but when I console.log the responseText I get an empty string?

When I say console.log(getErrors) I receive this in the console:
XMLHttpRequest {statusText: "", status: 0, responseURL: "", response: "", responseType: ""...}
onabort: null
onerror: null
...
responseText: {"content":[{"id":1,"timeStamp":"2015-03-20T00:01:44.761","provider":"foo","providerId":null,"lineNumber":1,"summary":"foo","description":"foo: 1"}...
responseType: ""
responseURL: "http//localhost:8080/errors/findAll"
...
I know I'm getting the data because I can see it in responseText but when I say console.log(getErrors.responseText) I'm getting an empty string. I'm not sure what I'm doing wrong.
Javascript:
var getErrors = new XMLHttpRequest();
getErrors.open('GET', '/errors/findAll', true);
getErrors.send();
//var response = getErrors.responseText;
console.log(getErrors);
console.log(getErrors.responseText);
Here is my working code in Javascript:
getErrors = function(url, callbackFunction) // How can I use this callback?
{
var requestErrors = new XMLHttpRequest();
requestErrors.onreadystatechange = function()
{
if (requestErrors.readyState == 4 && requestErrors.status == 200)
{
callback(requestErrors.responseText); // Another callback here
}
}
requestErrors.open('GET', url);
requestErrors.send();
}
function callback(data) {
console.log(data);
}
getErrors('/errors/findAll', callback);

Categories

Resources