I'm developing a script that performs a cross site call to a python webservice, which returns a xml.
This is the full code of the html page that executes the cross site call:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="./jquery.xdomainajax.js"></script>
<script>
jQuery.ajax({
type: "GET",
url: "http://api.notmywebsite.net/search/parameters",
async: true,
beforeSend: function(xhr) {
xhr.withCredentials = true;
},
success: function(data) {
alert(data.responseXML);
},
error: function(err){
alert("error: " + err.status);
}
});
</script>
</head>
<body>
<div id="xmlOutput"></div>
</body>
</html>
The problem is, of course, the script isn't working:
- When I call the webservice through the browser, the xml is successfully displayed.
- I'm using WebScarab to check if the answer has any content, and it has. The HTTP response has the right headers and the expected XML response.
- I debugged the python webservice to check if a call made by my request would return the expected XML, and it did.
After some research I came across the same-origin policy, for which I started using (hope i'm using it right) the following proxy: https://github.com/padolsey/jQuery-Plugins/blob/master/cross-domain-ajax/jquery.xdomainajax.js
The webservice is also called using php, through a "simplexml_load_file($url);", which returns the expected XML response.
I tried executing this same call (but using responseText instead of responseXML) to google, and it was successful.
The xml has the following format:
<OAI-PMH xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/OAI-PMH http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<record>
<header>
<identifier>oai:epimarketplace.net:empid:1066</identifier>
<datestamp>2012-06-25T14:54:01.058Z</datestamp>
<setSpec>resource</setSpec>
<downLink>http://api.epimarketplace.net/fetch/pid/empid:1066</downLink>
</header>
<metadata>
<em>
<metadataLink>http://api.epimarketplace.net/rawfetch/pid/empid:1066/datastream/EM</metadataLink>
<field name="PID">empid:1066</field>
<field name="em.dateSubmitted">2012-08-20T10:43:40Z</field>
<field name="em.generalDescription.subject">Behaviour</field>
<field name="em.generalDescription.type">Dataset harvested from social networks</field>
<field name="em.title"><script>XSS</script>
</field>
<field name="em.uploader.name">Tiago André Posse</field>
<field name="isCollection_b">false</field>
<field name="nComments">0</field>
<field name="nLikes">0</field>
</em>
</metadata>
</record>
</OAI-PMH>
Hoping you can help me,
Thanks in advance.
In order for the browser to correctly return an XML object using responseXML, you must ensure the following:
1.Your XML document is well formed( responseXML will always return null if not)
2.In Firefox, call request.overrideMimeType('text/xml') at the start of your Ajax request (upon instantiation) to explicitly tell the browser that the returned data will have a content type of "text/xml".
3.IE doesn't support the client side overrideMimeType() method, so you must ensure that your server returns the proper "text/xml" content header type for the XML file that is being returned.
NOTE: If your XML file is named with an extension of ".xml", most servers by default send out the proper "text/xml" headers, though if it is not, you'll want to modify your server settings to do so. See "XML documents and the Content-type pitfall in IE" for more info.
If any one of the above conditions are not met, the data returned will be as plain text, not an XML object as expected.
EDIT: I looked into your JQuery Ajax call(again) and guess what?! The responseXML will always be undefined, as you are trying to access it even before the AJAX request has completed. My solution would be to call the function under complete attribute instead of success.
Related
I am posting only 2 variables. If I do a direct POST using the form below it works.
<form action="http://someapi/post_html" method="post" enctype="multipart/form-data">
<input type="text" name="name" >
<textarea name="htmltemplate"> a html template of 3000 characters
</textarea>
<button type="submit">Submit</button>
</form>
When I use ajax to post the data I actually get a response back from the server max_input_vars limit of 1000 exceeded. How is it possible when I'm only sending 2 variables using ajax that I get that message?
I also tried using curl to do a POST and ended up receiving the same message.
$('form.ajax').on('submit',function() {
var formData = $('form.ajax').serialize();
formData += CKEDITOR.instances.textboxwyswygs.getData();
event.preventDefault();
$.ajax({
url: "http://someapi/post_html",
method:"POST",
data: formData,
success: function(response){
console.log(response);
}
})
});
Your formData looks broken - serialize() returns a JSON string and the CKEditor getData() returns a string of HTML.
Try this: synchronize the CKEditor value into the form before calling serialize and then your JSON will be correct. Try to console.log(formData) to check the formData before sending. So submitting the form without the syncrhonziation doesn't actually send the CKE content at all. This should be checked server-side to see what input it is getting.
Also the value of the ajax functions data member is expected to be correct JSON and servers might handle it in weird ways.
Other issues: $('form.ajax') does not actually target your HTML. Is this a correct example?
The event variable looks undefined, try naming it e and adding it as a parameter to .on('submit',function(e){..}.
You don't show the code where you actually replace the textarea with a CKEditor, it would be useful to see.
Need some help in the following case:
I have set an application as Liferay portlet and i am using JSF/Primefaces for builing my views. For data modelling i am using Hibernate.
In a certain view i load a so called "image annotator" which is using Javascript tools for gathering user input (annotation on an image canvas). This information i would like to be able to save in a file/database and then re-use when the user edits again a specific image.
Here is my view:
<h:head>
<script src="#{facesContext.externalContext.requestContextPath}/js/OpenLayers.js" />
<script src="#{facesContext.externalContext.requestContextPath}/js/image-viewer.js" />
<script src="#{facesContext.externalContext.requestContextPath}/js/xml2js/xml2json.js" />
<script src="#{facesContext.externalContext.requestContextPath}/js/xml2js/xml2json.min.js" />
...
</head>
...
<p:fieldset legend="Viewer">
<p:outputPanel layout="block" styleClass="imageEditorImagePanel" />
</p:fieldset>
....
So the image and the relevant jscript tools (OpenLayers) are loaded in imageEditorPanel placeholder.
The javascript code (image-viewer.js) gathers user input in a json (GEOJson) object, and this object i would like to pass to a back bean controller when Save button (jscript) is selected:
...
//define save button
var save = new OpenLayers.Control.Button({
title: 'Save', text: 'Save',
trigger: function(){
var GEOJSON_PARSER = new OpenLayers.Format.GeoJSON();
var vectorLayerAsJson = GEOJSON_PARSER.write(vlayer.features);
...
So i want to pass 'vectorLayerAsJson' object to a java controller (backbean) ...
I am trying to implement an ajax call like:
jQuery.ajax({
type: 'POST',
url: 'imageannotations',
contentType: 'application/json',
data: vectorLayerAsJson,
success : function(data) { alert("success")}
});
can anybody help on how am i going to make this ajax request as also how am i going to implement my controller class?
You can initiate a call to a java managed bean via Javascript using primefaces p:remoteCommand. Answers how to send the String as an argument can be found here.
In the managed bean/java controller, just have a String variable with getter/setter and an action method to start the unserialization (following is untested code):
#ManagedBean(name="testBean")
public class Test {
public String actionOnString() {
String value = FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap().get("param");
// do your unserialize and actions here
return "";
}
}
Within JSF have something like
<p:remoteCommand name="sendJSONToServer" action="#{testBean.actionOnString}" />
and as javascript on the desired position
sendJSONToServer({param: vectorLayerAsJson});
should do the job.
Direct ajax-push is also possible via PrimePush, using the athmosphere framework. Possibly, that might be overkill for what you try to achieve.
Update 1
Of course, when you get a JSON-Object serialized (so to say "n String format), you have to JSONize it in Javascript - this answer "How to parse JSON in JavaScript" might help you further regarding that.
Hope it helps...
I've built a simple web application using sitemesh and struts2 frameworks. Now I have some problem getting the right reponse with an ajax callback in a jsp. I'm using with success the same process in another web application, but using tiles with struts 1.
I try to explain the problem.
I have a jsp (decorated with sitemesh from a template called "basic-theme.jsp" with a decorator:title and a decorator:body tag).
The page has an input button, which calls a jQuery.ajax post function:
function checkRicevuta(){
var params = "actionToDo=checkRicevuta&idRicevuta="+$("#idRicevuta").val();
$.ajax({
type: "POST",
url: "addettoReclami",
data: params,
success: function(response){
$("#checkRicevuta-box").append(response);
}
});
}
url is correctly calling an ActionSupport class, which is processing 'params':
if(request.getParameter("actionToDo")!=null && request.getParameter("actionToDo").equals("checkRicevuta")){
logger.info("Avvio procedura di verifica ricevuta fiscale");
String idRicevuta = request.getParameter("idRicevuta");
if(dbController.checkRicevuta(idRicevuta))
request.setAttribute("message", "Ricevuta valida!");
else request.setAttribute("message", "Ricevuta non valida");
return "esitoRicevuta";
}
'esitoRicevuta' forwards to a simple jsp literally made only of two lines:
<% String message = (String)request.getAttribute("message"); %>
<p><%=message %></p>
because I'd like to append this simple response inside a div of the first jsp which made the ajax call.
The problem is that the response is also being decorated by sitemesh, so I pratically get a nested basic-theme.
In the sitemesh xml I set the exclude pattern not to process my /fragment/* path where is located the "response jsp":
<?xml version="1.0" encoding="UTF-8"?>
<decorators>
<excludes>
<pattern>/popup/*</pattern>
<pattern>/fragment/*</pattern>
</excludes>
<decorator name="basic-theme" page="/decorators/basic-theme.jsp">
<pattern>/*</pattern>
</decorator>
</decorators>
I said, using the same process with tiles and struts1, the problem does not happen.
Probably I'm wrong, but I'm supposing this is because response is appended inside the "caller jsp" so sitemesh decorates the page two times, one for the caller jsp's body and one for the fragment inside the caller jsp's body.
So I ask you... why this problem? Is there a solution to avoid this?
Thanks in advance
I am using this version of jQuery form plugin https://raw.github.com/malsup/form/master/jquery.form.js
getting an error on submit:
error on line form.submit();
SCRIPT87: Invalid argument. jquery.form.js, line 347 character 5
My code:
<form id="ajaxUploadForm" action="#Url.Action("Upload", "Home")%>" method="post" enctype="multipart/form-data" >
<fieldset>
<legend>Upload a file</legend>
<label>File to Upload: <input type="file" name="file" /></label>
<input id="ajaxUploadButton" type="submit" value="Upload" />
</fieldset>
</form>
$(function () {
$("#ajaxUploadForm").ajaxForm({
iframe: true,
dataType: "json",
beforeSubmit: function () {
// $("#ajaxUploadForm").block({ message: '<img src="/Content/themes/start/images/progress.gif" />' });
},
success: function (result) {
// $("#ajaxUploadForm").unblock();
//$("#ajaxUploadForm").resetForm();
$.growlUI(null, result.message);
},
error: function (xhr, textStatus, errorThrown) {
//$("#ajaxUploadForm").unblock();
//$("#ajaxUploadForm").resetForm();
$.growlUI(null, 'Error uploading file');
}
});
});
I am doing this upload in side simple model dialog.
May be some one may have any ideas how ti fix that?
If the controller action that you are POSTing to is returning JSON you might need to wrap it in a <textarea> tags as explained in the documentation:
Since it is not possible to upload
files using the browser's
XMLHttpRequest object, the Form Plugin
uses a hidden iframe element to help
with the task. This is a common
technique, but it has inherent
limitations. The iframe element is
used as the target of the form's
submit operation which means that the
server response is written to the
iframe. This is fine if the response
type is HTML or XML, but doesn't work
as well if the response type is script
or JSON, both of which often contain
characters that need to be repesented
using entity references when found in
HTML markup.
To account for the challenges of
script and JSON responses, the Form
Plugin allows these responses to be
embedded in a textarea element and it
is recommended that you do so for
these response types when used in
conjuction with file uploads. Please
note, however, that if there is no
file input in the form then the
request uses normal XHR to submit the
form (not an iframe). This puts the
burden on your server code to know
when to use a textarea and when not
to. If you like, you can use the
iframe option of the plugin to force
it to always use an iframe mode and
then your server can always embed the
response in a textarea.
I want to use ajax in jquery to get data for my page...
The problem is that the url which i call has some query strings to be sent along with it...
for example: the url which i call for getting data is:-
http://mysite.in.dataengine.aspx?t=abcde&token=h34jk3&f=xml
the data i get in response from this url can be in xml format or java script arrays(whichever i choose)
for eg...the xml wil look like this:-
<root version="1.0">
<Regions>
<Region SubCode="MWEST" RCode="west"/>
<Region SubCode="MCENT" RCode="north"/>
<Region SubCode="THAN" RCode="south"/>
</Regions>
</root>
and the javascript array would look like this :-
Region = new Array();
Region.push(new Array('MWEST', 'west'));
Region.push(new Array('MCENT', 'north' ));
Region.push(new Array('THAN', 'south'));
So when i get the data i want to store it in a drop down box.(using ajax)
Note I can get either xml OR javascript arrays as the returned data, not both together.
You can make an ajax call along with parameters like this:
var paramsData = "t=abcde&token=h34jk3";
$.ajax({
type: "GET",
url: "dataengine.aspx",
data: paramsData,
dataType: "xml",
success: function(xml){
//process xml from server
}
});
I would suggest you to get the data in JSON format, as Json comes natively to javascript and it much easliy manipulated using javascript as compared to XML. The easiest way i can see to work on your problem is to store all your data whether xml or json & put it inside a hidden div and then use jQuery to populate that data in a drop down box.
Here is an amazing jquery plugin with example that should ease your work
http://plugins.jquery.com/project/jqueryclientdb
Just parse it. I"m not sure if this will work, but it might:
xml = ...
region = new Array();
$(xml).find('Region').each(function() {
region.push(new Array($(this).attr('SubCode'), $(this).attr('RCode'));
});
Thanks for your help guys...but i have found the solution....Like i said...that i get in return either xml or javascript array...So..i'm using javascript arrays.. and using a function in jquery*($.getScript)* which fetches an external javascript code via ajax...Thus i am getting all my data now through ajax in jquery...