Here is what I am doing
var url_action="/temp/SaveConfig";
var client;
var dataString;
if (window.XMLHttpRequest){ // IE7+, Firefox, Chrome, Opera, Safari
client=new XMLHttpRequest();
} else { // IE6, IE5
client=new ActiveXObject("Microsoft.XMLHTTP");
}
client.onreadystatechange=function(){
if(client.readyState==4&&client.status==200)
{
alert(client.responseText);
}
};
//dataString=document.getElementById("tfile").value;
client.open("POST",url_action,true);
client.setRequestHeader("Content-type", "multipart/form-data");
client.setRequestHeader("Connection", "close");
client.send();
But at the server side i get org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
Where am i going wrong?
After reading reply from Aticus
Here is what i did and file is getting uploaded.
var form=document.forms["mainForm"];
form.setAttribute("target","micox-temp");
form.setAttribute("action",url_action);
form.setAttribute("method","post");
form.setAttribute("enctype","multipart/form-data");
form.setAttribute("encoding","multipart/form-data");
form.submit();
but now how do i recieve values from servlet to perform some kind of checking apart from JSON?
Until the upcoming XMLHttpRequest version 2, you cannot upload a file using Ajax.
Most of the current Ajaxbased file uploaders use an <iframe> hack. It uses JS code to create an invisible <iframe> where the form is been copied in and is been submitted synchronously. The parent page will just stay unchanged and it looks like as if it is been done asynchronously.
To get best crossbrowser compatibility and to minimize headaches with regard to writing crossbrowser compatible code, I'd strongly recommend to grab an existing JS library which excels in handling ajaxical stuff and traversing/manipulating HTML DOM tree, such as jQuery. It comes with plethora of form upload plugins, the simplest one being the jQuery-form plugin. It supports file uploads as well with help of the hidden <iframe> hack. It's then basically as easy as
<script src="jquery.js"></script>
<script src="jquery-form.js"></script>
<script>
$(document).ready(function() {
$('#formid').ajaxForm(function(data) {
// Do something with response.
$('#result').text(data.result);
});
});
</script>
...
<form id="formid" action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" />
</form>
<div id="result"></div>
In the server side, just have a servlet which processes the request the usual way, either with the Servlet 3.0 provided HttpServletRequest#getParts() or with the good old Apache Commons FileUpload (examples here).
Either way, you can just return the response as JSON the usual way
Map<String, Object> data = new HashMap<String, Object>();
data.put("result", "Upload successful!");
// ...
response.setContentType("application/json");
resposne.setCharacterEncoding("UTF-8");
resposne.getWriter().write(new Gson().toJson(data));
For more Ajax-Servlet-JSON examples, check this answer.
Files are not transmittable via asynchronous requests such as this. You'll need to submit it in a multipart form.
Depending on what the file is you could store the data in a post variable.
Related
I have OData REST APIs protected with SAML 2.0(POST binding) and I have Angular 2+ client application. How can I call these REST APIs using Angular application?
When I use Angular HTTP client
import {Http, RequestOptions, Request, RequestMethod} from '#angular/http';
I'm getting form with continue button to Note:Since your browser does not support JavaScript, you must press the Continue button once to proceed.
If I hit same REST API URL directly in browser, then browser redirects to IDP and then, after successful authentication, IdP redirects back it to REST API.
The same behavior is observed on Postman, but they are fixing it by enabling JS script preview.
Here is Angular code which i tried:
this.POST('https://<RESTAppfqdn>/odata', {"ID": "2"}).subscribe(data => {
console.log(data)
})
}
POST(url, data) {
const headers = Object.assign({
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json;vnd.ptc.ilm.webui2.0=true;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
});
var requestoptions = new RequestOptions({
method: RequestMethod.Post,
url: url,
headers: headers,
body: data
})
return this.http.request(new Request(requestoptions))
.pipe(map(res => res.json()));
}
Here is response I can see in browser's network tab:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
</head>
<body onload="document.forms[0].submit()">
<noscript>
<p>
<strong>Note:</strong> Since your browser does not support JavaScript,
you must press the Continue button once to proceed.
</p>
</noscript>
<form action="https://<Idpfqn>:9031/idp/SSO.saml2" method="post">
<div>
<input type="hidden" name="SAMLRequest" value="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1sMnA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgQXNzZXJ0aW9uQ29uc3VtZXJTZXJ2aWNlVVJMPSJodHRwczovL0tJU0pBREhBVjJMMS9zYW1sL1NTTyIgRGVzdGluYXRpb249Imh0dHBzOi8va2lzamFkaGF2MmwxLnB0Y25ldC5wdGMuY29tOjkwMzEvaWRwL1NTTy5zYW1sMiIgRm9yY2VBdXRobj0iZmFsc2UiIElEPSJhM2UzOTMyZjAzNTNmNWI3NTFoYmc4ZWpmY2lkNTViIiBJc1Bhc3NpdmU9ImZhbHNlIiBJc3N1ZUluc3RhbnQ9IjIwMTktMDQtMjVUMDY6MTc6MjUuOTQzWiIgUHJvdG9jb2xCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1QT1NUIiBWZXJzaW9uPSIyLjAiPjxzYW1sMjpJc3N1ZXIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPmh0dHBzOi8vS0lTSkFESEFWMkwxL3NhbWwvbWV0YWRhdGE8L3NhbWwyOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2EzZTM5MzJmMDM1M2Y1Yjc1MWhiZzhlamZjaWQ1NWIiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNzaGExIi8+PGRzOkRpZ2VzdFZhbHVlPlNDc3dxRG5FTThNWEJvSnZkRGhrdEE3dGF5VT08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+YkxTd3pjRFhYUmNQV1VYa2hHbXB4RXZEQ3JlRWFpc2tka2drTzl5eGpkdGFlalhnSEVBNHRQNWhuL2FyRVh4T0NxWHlmWnFBRXFZZFduTE5vODJyNXZoQ1F2SGhWdEJHTUY0T1FSbXlDT2FwUHRPamdINWtpRW1uaVVHNHduaEpERCsxRWR3L2x2ZFlJd0svSEhCSE8zV2p4eTZ3aW9hbUhMRGczYWNNM0QzdHNMMFR0VlM0RVZETncxeFBmeTdUWTd6WVZqYWUrcmZqRm9IZUlEQlZYdFNnS2xSL2RHbW1DMXBaTDFydWVsZHkzSEJRV3dYVWx5S1NRa09oNU9VWnBCeWttMHBERDhmNnA4UVV3Uy8zTEtxd3hvc1NiWlVIMlJoUHI0RFIwTDMwQjNzSmlka1JKMGI0eUdHNlFzZnlGY3lVZERxdHVDS3FhVkpMR1htSXNnPT08L2RzOlNpZ25hdHVyZVZhbHVlPjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSURYVENDQWtXZ0F3SUJBZ0lFVXZvcnFEQU5CZ2txaGtpRzl3MEJBUXNGQURCZk1Rc3dDUVlEVlFRR0V3SnBiakVMTUFrR0ExVUUNCkNCTUNiV2d4RFRBTEJnTlZCQWNUQkhCMWJtVXhEREFLQmdOVkJBb1RBM0IwWXpFUE1BMEdBMVVFQ3hNR2NIUmpibVYwTVJVd0V3WUQNClZRUURFd3hMU1ZOS1FVUklRVll5VERFd0hoY05NVGt3TkRJME1UZzBOekV3V2hjTk1qQXdOREU0TVRnME56RXdXakJmTVFzd0NRWUQNClZRUUdFd0pwYmpFTE1Ba0dBMVVFQ0JNQ2JXZ3hEVEFMQmdOVkJBY1RCSEIxYm1VeEREQUtCZ05WQkFvVEEzQjBZekVQTUEwR0ExVUUNCkN4TUdjSFJqYm1WME1SVXdFd1lEVlFRREV3eExTVk5LUVVSSVFWWXlUREV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXcNCmdnRUtBb0lCQVFDblM2MmdHQ2llcHZJMXFVdCt4a1d1bjJRenlUWUlLay9DQ0w3WkxVUlkyVmluS0w4UUFGb0xnM0s2bGJCaTVPeEENCjI2em9ZY3cyVHJ5a1FmL2ZuSG04eXpEVWJWSzlmZ0NXVXBzT2tOZnUyMHVZUzc2cTBna0tmbGFFR2Q4UzFFUStVUGMvT0pkem5NTXMNCkpzckZldXZYMVpqZFMzWG9mZlBDZXcvOGdIQzR2dTU1V0tGSDhvODUxQWdRdXRrNzlUYUpYUm5zN0VpUVhvMkVBVnNTUWIrZXpoWGYNCnJuYXNMN1BhUGFWT0JQV1RBTi83VERSZEs4R1RiUHRrWG8wMnIxZnNoZk5rRW05VDhROTBFNmtmU1l6emt3MXByRktwY1RncTZsbmUNClFFMk4zNEpCVTdjUHlYVW8yRHVNNkxVVXZndWFLK2xDK05TamZENWliMFNTcDdtdkFnTUJBQUdqSVRBZk1CMEdBMVVkRGdRV0JCU28NCmxUS3d3dkoxdzBsZjkwZURPWTluUlY4bjJqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFYRzA4ZWphdjQxYWJtQS9jZkNZUFQrWVINClhQSnZzQ1F1YTJRempRSy9IMDdNclJsOTVCSkkzeUJEQ1pJaW9ndU5YbS9sbHVxYzV1VWJtekdBenBFM3MybnZtbjQ0bjBhUVYyd28NCkxja2NiWUZJUkNFRFhOZXFZUEUrZFVGdVgwSEJ5dlFqNU9FSU9wZTlYTzUrZ1lFUUlXZWxTZXFibUF0UmRuWi84ZWlFY3h6bEFaTlINCkRITDlxdjloK2doNFpPM3BkRVNLdWM3Z0NKODFXVGNueUN1QS9ZS1ZMR2lnM0plbEJJYkhwZTVXcXBaR3dPUG9WYk82cVViTzlHQjUNCmxVQkxYRlF3cmVSazlTV3JVQkV5Wi8yQ3ovY1UvVjRnSms4cGdTWTFPVHNOUmpGanZKVjd1TnBQeEsxam1nRkRsakV5aXpHay96WGENClJDNjE1VVhIbExpb093PT08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48L3NhbWwycDpBdXRoblJlcXVlc3Q+"/>
</div>
<noscript>
<div>
<input type="submit" value="Continue"/>
</div>
</noscript>
</form>
</body>
</html>```
As Angular http client reside in browser, browser should take care of handling this post form submission and redirection work but that is not happening. Is there any way by which i can tell browser to handle such responses?
As there is form in response received from server, I have submit that form.
Hence, I have created a div (ex. auth) in index.html and when the response contains the form then submit that. Here is that code.
if (res['error']['text']) {
let authDiv = document.getElementById('auth')
authDiv.innerHTML = res['error']['text']
var f1 = authDiv.children[1]
f1.submit()
return new HttpResponseFailAction([res['error']['text']])
}
But then we will face another issues with that:
Ex. The auth challenge received from IdP has to be displayed.
Basically, we need to act like browser and any coming requests we need to handle.
Hence, I decided to discarded this approach and added SAML SSO support to client application itself.
I have spring mvc application
Sometimes on our site we can see that in html exists img tag but actually url is broken.
Now we want show default image for all these situations.
How can we handle it in single place and we should hit at this place only when we want to load image.
You can get it using jQuery. On the document.ready you can check the url of all images, and check if the images are valid. If not you can just change for your image.
Here is the jQuery code (you must add it on all your pages):
$(document).ready(function(){
var images = $('img').each(function(i, image){
checkSrc(image);
});
});
function checkSrc(image){
$.get($(image).attr('src'), function() {
//succes, we do nothing
}).fail(function() {
$(image).attr('src','https://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Cristiano_Ajax.jpg/220px-Cristiano_Ajax.jpg');
});
}
Here the html:
<img src="notexisting.jpg"/>
Working fiddle: http://jsfiddle.net/bx5kkoun/
WARINING
I don't recommend to do this because you have to request twice the images.
You can achieve it as well using Java Filter, but you must check as well the url of all images from server, but it's the same situation.
How about this:
<img src="image.gif" onerror="loadDefaultImage()">
This solution is cross-browser, but not IE8 and below.
You have many options for the loadDefaultImage function, you could use the jQuery method already suggested (just use the fail part), here is another suggestion, or just google "image tag onerror example" and select an option that works for you.
I think resolving it on the client side is the most efficient way to go. It will only attempt an extra request if there is a failure. If you attempt a solution on the server side, you would have to test for success/failure and then modify the markup sent to the browser. The browser will have to load even the successful images again as the page is rendering.
Here is a possible implementation:
function loadDefaultImage(element) {
$(element).attr(
'src',
'https://placehold.it/100x100'
);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="width:100px;margin-right:100px;display:inline-block;">
<img src="image.gif">
</div>
<div style="display:inline-block;">
<img src="image.gif" onerror="loadDefaultImage(this)">
</div>
I'm working with a third party that is generating div content based on a post response from my server (java servlet). One problem I have is that we have a list of radio buttons leveled in a form.
When I hit submit on that form, I need to make a post call to my server and re-render that div in the third party site. I have used different variations of jQuery to no avail.
I've included the most recent jQuery (also tried a sub 1.4 release of jQuery). When I hit the submit button on my form, I just render the same page and I do NOT render a call to the server.
How can I do this, update a div on the local page that renders my post results based on a form I write? Below is what I currently have:
Form:
<form action='\' id=\"form1\">... radio buttons ... </form>
<input hidden field name = value passed from Java method>
<input hidden field id = value passed from Java method>
<input hidden field the value of the selected checkbox>
HTML:
<script language='Javascript' type='text/javascript'>
$(\"#form1\").submit(function(event) {
event.preventDefault();
var $form = $( this ),
name2= $form.find( 'input[name=\"name\"]' ).val(),
id2= $form.find( 'input[name=\"id\"]' ).val(),
url = $form.attr( 'action' );
$.post( url, { name2:name, id2:id },
function( data ) {
var content = $( data ).find( '#content' );
$( \"#this_div\" ).empty().append( content );
});
});
</script>
Sending AJAX Requests from a Third Party site to your server:
Due to browser security requirements, it is not currently possible to make cross-domain AJAX requests to a third-party server. This means that the $.post request is limited to what is referred to as the same-domain policy.
Thus, if your server is example.com and the third party server is domain.com, domain.com cannot make AJAX requests to your server.
However, there is a technique you can use to circumvent this browser security. While it's not possible for XMLHttpRequests to be made cross domain, JavaScript <script> tag blocks can load JavaScript from any domain.
Script tag remoting, or JSONP, involves using a script tag to send a request to your server:
Script tag:
// from domain.com to your server, example.com, make a request using a script tag
var urlWithParams = "http://example.com/getHTMLForm.do?id2=" + id2 + "&name2" + name2;
var script = document.createElement("script");
script.setAttribute("type","text/javascript");
script.setAttribute("src", urlWithParams);
// create a script tag, which invokes your servlet
document.getElementsByTagName("head")[0].appendChild(script);
getHTMLForm.do is a hypothetical servlet that you're currently using to post the data and get HTML in the response. Instead of passing the parameters in the Request body using POST, you'll pass the data as query parameters.
Server response::
The server then responds with JSON that you generate on the server, but it's wrapped -- or padded -- inside a JavaScript function that is defined on the web page making the request.
// your response from your server
insertFormOnPage({"html":"<form action='#'><input name='name' /><input name='id' /></form>", "elem" : "#content"});
Third party Client side code:
For this technique to work, the third party site must have a function defined that matches the one your server will return:
function insertFormOnPage( data ) {
alert( data.html ); // prints the HTML for debugging
alert( data.elem ); // prints the selector you want to insert into
// inject the HTML into the #content DIV
$( data.elem ).html( data.html );
}
HTML on the third party site:
<!-- Let's just assume the third party site's DIV is empty for simplicity -->
<div id="#content"></div
Explanation:
Your server returns pure JavaScript to the client side, as JavaScript, as a function that executes immediately.
The function receives the following items as properties in a JavaScript object: The HTML, and the div id.
The function accesses the object's html and elem properties to access both the html string and the selector.
Using jQuery, the function injects the HTML inside the DIV#content element.
The last and final thing you should know about this technique is that it only supports GET methods, since that is how JavaScript is fetched from the server. This means that you'll need to make sure your server is configured to accept GET requests for this data and not POST requests.
JSONP Using jQuery:
While the above solution helps describe the concepts of what is happening under the hood, you may also want to check out jQuery getJSON. Specifically, look at the JSONP examples, which are the only way to make cross-domain requests without reloading the page.
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
tags: "cat",
tagmode: "any",
format: "json"
},
function(data) {
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});
The final stage of my project is to connect my website to a bank payment gateway to allow people to buy things using credit cards but without storing any credit card data on my site. I've been on Google and stackoverflow and think I'm on the right track but am obviously doing something wrong.
The idea is that as the form opens an http-post happens which sends a set of parameters to the gateway which responds with a nice long encryption string which I use to submit the actual order. I'd appreciate some help here as I'm now quite stuck.
<form method="post" action="/A55D74/fwcdirect.nsf/encrypt?OpenForm&Seq=1" name="_encrypt">
<input type="hidden" name="__Click" value="0" /><form action="https://encryption-gateway-url.e" method="post">
<script>
var url = "valid-url";
var params = "clientid=12&password=xyz&chargetype=Auth¤cy=42&total=1.00";
xmlhttp = new XMLHttpRequest();
xmlhttp.open("post", url, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(params);
return xmlhttp.responseText;
</script>
<input type="hidden" name="returnurl" value="http://www.mywebsite.co.uk/">
<input type="hidden" name="merchantdisplayname" value="Website + Shopping cart">
<input type="submit" value="10.00">
</form>
9th April: I still haven't cracked the problem yet although am getting an error response from the gateway server, I'm currently exploring dojo which is looking very promising and as a bonus comes pre-installed with Lotus Notes client & server (Domino 8.5.1 has dojo 1.3.2).
My guess would be you are supposed to do this on the server, not in the client where same-origin policy prevents you from posting and reading data to a different domain.
I.e. The customer loads the final payment page; before its returned from your server you post your billing details to the the bank, get the encrypted response and append that as a hidden field in the form the user will actually submit for payment.
Its supposed to be a way to prevent users from messing about with the client/amount params, they should never see them at all.
(This looks like EPDQ, if so that's definitely what your supposed to do as I use it myself!)
XMLHttpRequest is a callback method, so it means you should create a callback function to process the responseText.
e.g.
var url = "valid-url";
var params = "clientid=12&password=xyz&chargetype=Auth¤cy=42&total=1.00";
xmlhttp = new XMLHttpRequest();
xmlhttp.open("post", url, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// add this line
xmlhttp.onreadystatechange = callback
xmlhttp.send(params);
// remove this line
//return xmlhttp.responseText;
// add a new function
function callback(req, id) {
if(req.readyState == 4 && req.status == 200) {
alter(req.responseText);
}
}
Is there a multipart POST library out there that achieve the same effect of doing a POST from a html form? for example - upload a file programmingly in Java versus upload the file using a html form. And on the server side, it just blindly expect the request from client side to be a multipart POST request and parse out the data as appropriate.
Has anyone tried this?
specifically, I am trying to see if I can simulate the following with Java
The user creates a blob by submitting an HTML form that includes one or more file input fields. Your app sets blobstoreService.createUploadUrl() as the destination (action) of this form, passing the function a URL path of a handler in your app. When the user submits the form, the user's browser uploads the specified files directly to the Blobstore. The Blobstore rewrites the user's request and stores the uploaded file data, replacing the uploaded file data with one or more corresponding blob keys, then passes the rewritten request to the handler at the URL path you provided to blobstoreService.createUploadUrl(). This handler can do additional processing based on the blob key. Finally, the handler must return a headers-only, redirect response (301, 302, or 303), typically a browser redirect to another page indicating the status of the blob upload.
Set blobstoreService.createUploadUrl as the form action, passing the application path to load when the POST of the form is completed.
<body>
<form action="<%= blobstoreService.createUploadUrl("/upload") %>" method="post" enctype="multipart/form-data">
<input type="file" name="myFile">
<input type="submit" value="Submit">
</form>
</body>
Note that this is how the upload form would look if it were created as a JSP.
The form must include a file upload field, and the form's enctype must be set to multipart/form-data. When the user submits the form, the POST is handled by the Blobstore API, which creates the blob. The API also creates an info record for the blob and stores the record in the datastore, and passes the rewritten request to your app on the given path as a blob key.
You don't need a library; this is possible with the stock Java classes (example).
On the server side you will implement a Java Servlet solution that makes parsing HTTP request parameters very simple.
A complete and de facto standard HTTP implementation (included for example in the Android platform) you will find at Apache httpcomponent