How to handle octet-stream coming from XMLHttpRequest - ajax

I want to download files from server with AJAX calls.
It can be done easily by using iframe as follow:
var ifrm = document.getElementById("fileframe");
ifrm.src = "DownloadFile?fileid="+fileid;
But I have more complicated issue.
In some cases, instead of application/octet-stream, response with content type of 'text/html' is given back by the back end.
I plan to use XMLHttpRequest calls to the backed for downloading files.
By using XMLHttpRequest how can I make a browser to popup a save file dialog to handle application/octet-stream?
// connect function handles the XMLHttpRequest communication with the backend
var connection = connect('DownloadFile','fileid='+fileid);
connection.onreadystatechange = function(){
if(connection.readyState == 4) {
var contentType = connection.getResponseHeader('Content-Type');
if(contentType == 'application/octet-stream'){
// here I want to make the browser popup a save file dialog
// for the incoming octet stream
// maybe I can direct stream to an iframe, but how??
}else{
alert(connection.responseText);
}
}
if((connection.readyState == 2)||(connection.readyState == 3)){
}
}

I can think of two options.
Send a HEAD request first and decide the action based on content
type.
Issue a GET request knowing what to expect.
Create a Data
URI (RFC 2387) with the data and open it using window.open.
Browser will open a dialog box for content it cannot render.

Related

How do i request an Array from the controller from inside a javascript code

I am using Spring boot, JPA with mysql, and thymeleaf and openlayers for the map.
So i have a map, and on this map there are dynamically generated markers for different places. What I want is when I click any of those markers to send the name of the marker to my controller and in response get an array of fishes that can be caught in this specific area and then display the names and pictures of the fishes in a dynamically generated list located on the sidebar . I cant think on how I can achieve that. Ive made a HTML page to show how I want it to look.
I was thinking about making a get request and giving the name as a path variable but then idk how I can do that request from the javascript when the button is clicked. Any ideas or concepts that I can read about are apreciated.
Most DOM elements in html are accessible in javascript via something like document.getelementbyid and typically if I remember this correctly most of the objects you can do something like domobject.addEventListener("click", myScript); and in myScripy make an http call to spring requesting the list of fish. I recommend setting some breakpoints in your JavaScript code via the dev console in your browser and looking through some of the objects that are produced
You can make a get request like described here. developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
Clicking on the markers would be similar to this example https://openlayers.org/en/latest/examples/icon.html, but instead of showing a popup you make a GET request for more data
map.on('click', function (evt) {
const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature;
});
if (feature) {
const name = feature.get('name');
// now make get request
// ....
}
});
If you are requesting an image you could use xhr as in https://openlayers.org/en/latest/apidoc/module-ol_Tile.html#~LoadFunction or you could use fetch, similar to:
fetch(url).then(function(response) {
if (response.ok) {
return response.blob();
}
}).then(function(result) {
if (result) {
const imagesrc = URL.createObjectURL(result);
}
});

Sending data from listener (of httpRequestObserver) to addon panel (iframe)

I am trying to create a fire-bug like extension for firefox which is actually dev-tool extension. I have registered httpRequestObserver to observe http-on-examine-response event. I have a listener with below method implemented.
onDataAvailable: function(request, context, inputStream, offset, count) {
//I get the request URL using request.name
var responseData = getResponseData(); // gets data from inputStream
// Now I need to render this responseData into panel's iframe
}
I have created the above script as a module and included it in main.js. I could not find out how the data from this script could be sent to the script included in panel's HTML.
I read about Content Script and port.emit & port.on but I think Content Script won't come into picture since I don't want to touch the actual page's DOM. Want I want to do is intercept the HTTP response and log it into devtool panel.
Thanks in advance.
Take the response string received and make a data url out of it. Then with your content script do a document.write(dataurl) or do window.location = dataurl.
How to make dataurl:
var responseData = getResponseData();
var dataurl = 'data:text/html,' + encodeURIComponent(responseData);
I hear that widgets in sdk have a content option where you can specify this data url:
'content' option in panel, which would enable you to specify HTML content directly, as you can with a widget, as a result of which I've raised bug 692675.
Can also be done like this:
var HTML = '<html><p>Hi there</p></html>';
var panel = require('panel').Panel({
contentURL: "data:text/html, " + encodeURIComponent(HTML)
});
panel.show();

How to parse JSON using DOJO AJAX and REST

I am trying to send a request to a REST server using DOJO AJAX, however I get a null object as result (console):
You CLICKED = click clientX=34, clientY=13
JSON loaded from server: null
Here is my code:
// JavaScript Document
// load requirements for declarative widgets in page content
require([ "dojo/parser",
"dojo/dom",
"dojo/domReady!",
"dijit/form/Button"
]);
// Start initializing
dojo.ready(function(){
dojo.connect (
aBut1,
"onClick",
function(e){
console.log('You CLICKED = ', e);
dojo.xhrGet({
// The URL of the request
url: "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/find",
// Handle the result as JSON data
handleAs: "json",
// content
content: {f:"json", searchText:"new", contains:"true", searchFields:"state_new", layers:"2", returnGeometry:"false" },
// The success handler
load: function(jsonData) {
// Create a local var to append content to
console.info("JSON loaded from server: ", jsonData);
},
// The error handler
error: function() {
console.log('JSON log Error');
}
});
});
}); // End dojo.ready
This is the REST url I would like to use:
http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/find?searchText=new&contains=true&searchFields=state_name&sr=&layers=2&returnGeometry=false&f=json
I save the result of this URL in a json file and AJAX works reading that file and returning an object with 4 items. It is not using REST URL.
Thank you
I believe you are trying to use dojo.xhrGet to access a different domain, which it cannot do.
Limitations
dojo.xhrGet (and other functions in the same line: dojo.xhrPost,
dojo.xhrDelete, dojo.xhrPut), are bound by the ‘same domain’ security
policy of the browser. This means that they can only establish a
connection back to the same server that served the HTML page. If you
wish to use this API to talk to servers other than the one that
originated your page, then you will have to use a proxy on your
originating server and have it forward the requests. The only other
solution to working around the same domain restriction is to use
alternate IO methods, such as dojo.io.script.
http://dojotoolkit.org/reference-guide/1.7/dojo/xhrGet.html
That's not much to go on. What happens if you use curl to make a request to that URL?
Are you using Dojo 1.7? If so, maybe the Ajax Quickstart docs can help (I linked directly to the AMD-style, since that's probably what you should be using if you can). There are also more detailed docs on xhrGet.

Issue submitting wysiwyg data through Ajax

I am Using Cl Editor On a Cms in a working on, Everytime i submit data through ajax i am having problems with it.
Let's say i write 10 lines in my wysiwyg editor but i only receive 3 or 4 in php, after some debugging in firebug what i have noticed is the html i am sending through ajax contains a span with class "Apple-converted-space" <span class="Apple-converted-space"> </span> i am able to get everything before this span, but the text after this span is missing. I have no idea what it is. Let me write my code for better understanding.
To get cleditor data
var data = $(".cleditorMain iframe").contents().find('body').html();
Ajax Form Submission
if(window.XMLHttpRequest)
{
xmlhttp = new window.XMLHttpRequest();
}
else
{
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == '4' && xmlhttp.status == '200')
{
}
}
parameters = 'data=' + data
xmlhttp.open('POST', 'libs/make_procedure.php', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send(parameters);
return true;
I have also tried jquery ajax method.. same problem exists there, so please do not ask me to use the other way to submit data via ajax.
Thanks
You may want to check whether it is javascript that is not sending correct data or your backend that is not able to receive it.
So first you should debug in javascript by writing an alert(data); statement right after you get the data from that cieditor control, and see what do you get there. Use Firefox and you can also copy the html using mouse pointer from the alert box. (which is not possible in IE)
You should also check the cieditor specs to see if there is any easier way to get data in javascript.
You may also want to consider using CKEditor.
You are posting the data without escaping the contents of the data. Since the & is the seperator for different fields in a post, data will contain only the part up untill the first &. Use encodeURIComponent to escape the data value.
Change the line
parameters = 'data=' + data
to
parameters = 'data=' + encodeURIComponent(data);
See also: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent

TinyMCE not working in http request xhr ajax generated page

So i I have a page that contains links that call an httpRequest. The request calls a php file that grabs data from mysql and pre populates a form which is then returned to the browser/webpage. My problem is that when the page is returned to the browser via the httpRequest/ajax the text area does not display the tinymce editor, it just displays a normal text area. It looks like my request and ajax is working fine the text area just doesn't have the tinycme editor on it.
When i don't use ajax it works fine but when i put it in a separate file and call it via ajax it doesn't bring in the tinymce editor.
Does anyone know how to fix this problem so that my ajax generated page displays the text area with the tinymce editor. Thank you.
Lets presume that your thinyMCE instance is initialized with code below
// initialize tinyMCE in page
tinyMCE.init({
mode: "textareas",
theme: "advanced"
});
and you have some kind of button somewhere in the page. For purpose of this tip, i will not give it any ID but you may. Now, using jQuery you can easily attach event handler to that button which will call through AJAX your server and take content which you want to put tinyMCE editor. Code which will do such job would look somehow like below.
$(function() {
$("button").bind("click", function() {
var ed = tinyMCE.get('content');
ed.setProgressState(1); // Show progress
$.getJSON('/page/12.json', { /* your data */
}, function(data) {
ed.setProgressState(0); // Hide progress
ed.setContent(data["body"]);
}
});
});
});
You can see that on button.click ajax will call url /page/12.json which will return JSON as response. bare minimum of that response could be:
{
title: "Page title",
body: "<html><head><title>Page title</title>......</html>"
}
I attached anonymous function as callback which will handle response from server. and hide progress indicator which is shown before ajax call.
About JSON
JSON is shorten of JavaScript Object Notation. It is JavaScript code!!! So don't be confused about it. Using JSON you can make javascript object which can have attributes you can use later in your code to access particular peace of data which that object "holds". You can look at it as some kind of data structure if it is easier to you.
Anyway, to show you how this JSON can be created by hand look at examples below
var data = new Object();
data.title = "Page title";
data.body = "<html....";
or
var data = {
title: "page title",
body: "<html...."
};
it is very same thing.
If you want to learn more about JSON point your browser to http://json.org.
===== alternative =====
Alternative to json solution could be just plane ajax call to server and response can be plain HTML (from your question I can assume that you have something like this already). So instad of calling $.getJSON you can use $.get(url, callback); to do same thing. The code at the top of my answer will not dramatically change. Instead of geting JSON in response you will get string which is HTML.
----------- BOTTOM LINE -------
I prefer JSON since it can be easily extended later with other attributes, so there is no painful code changes later ;)
Problem here will be that when you return the full page and render it using the ajax response, your tinymce instance has not been shut down before.
In order to do this you can call this small piece of code before you render the ajax response:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
In this case the editor should initialize correctly. You are not allowed to initialize a tinymce editor with the same id before shutting the first one down.
Strangely i ran into this problem yesterday. Following code should work, but YMMV. Trick is to use the correct steps in ajax events. I used the Regular TinyMCE and made use of the jQuery library already included.
Following goes into your tinyMCE initialization tinyMCE.init() . All of the below block should be outside the document.ready.
myTinyInit = {
//.......All essential keys/values ...........
setup : function(ed) {
ed.onChange.add(function( ed ) {
tinyMCE.triggerSave();
}) }
//.....................
};
// Init the tinyMCE
tinyMCE.init(myTinyInit);
This ensures the content is being saved regularly onto the textarea that holds the value. Next step is setting up the request events.
Normally tinyMCE mceAddControl before the ajax post and mceRemoveControl after the ajax success should do the trick. But I found that often does not work.
I used the form as the jQuery selector in my case.
jQuery( '.myForm' )
.find( 'textarea#myTextArea' )
.ajaxStart(function() {
// If you need to copy over the values, you can do it here.
// If you are using jQuery form plugin you can bind to form-pre-serialize event instead.
// jQuery( this ).val( tinyMCE.get( jQuery( this ).attr( 'id' )).getContent() );
}).ajaxSend( function() {
// ! - step 2
// My case was multiple editors.
myEds = tinyMCE.editors;
for( edd in myEds ) {
myEds[ eds ].remove();
}
// tinyMCE.get( 'myTextarea' ).remove();
// strangely mceRemoveControl didnt work for me.
// tinyMCE.execCommand( 'mceRemoveControl', false, jQuery( this ).attr('id'));
}).ajaxSuccess(function() {
// Now we got the form again, Let's put up tinyMCE again.
txtID = jQuery( this ).attr( 'id' );
// ! - step 3
tinyMCE.execCommand( 'mceAddControl', false, txtID );
// Restore the contents into TinyMCE.
tinyMCE.get( txtID ).setContent( jQuery( this ).val());
});
Problems i came across :
Using mceRemoveControl always gave me r is undefined error persistently.
If you get a blank tinyMCE editor, check the DOM whether the ID of the textarea is replaced with something like mce_02, this means that TinyMCE is being initialized again or something is wrong with the order. If so, the tinyMCE is duplicated with each save.
if you are new to JS, I recommend using jQuery with the form plugin, it might be easier for you. But do use the regular non-jquery tinyMCE, as it is well documented.
I fixed this problem by recalling the function after the ajax call. In this part of my ajax:
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("Content").innerHTML=xmlhttp.responseText;
tinymce();
Now it works fine.

Resources