I'm working on the problem for almost one day,and I can't figure out a solution.
I want to add a download service into my jsp page,and the code like this:
response.setHeader("Content-Disposition","attachment;filename=authData"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+".csv");
PrintWriter out = response.getWriter();
and I use a trigger button to link to background.and the codes like this:
<input type="submit" class="btn_sure fw" value="query" onclick="queryAuthDataList();"/>
<input type="reset" class="btn_cancel fw" value="reset">
<input type="submit" class="btn_sure fw" value="download CSV" onclick="exportAuthDataList();" >
and the following onclick funtion like this:
function exportAuthDataList(){
$("#queryAuthDataForm").attr("action","export").submit();
}
function queryAuthDataList(){
$("#queryAuthDataForm").attr("action","query").submit();
}
for some reasons , I must use GET to collect the tag names and values in jsp file.
Here comes the problem,when I select data from DB2,and there're many results,I must paging them,But when I click next page,it's starting download csv file automaticly.I define different redirect keywords in Jquery,but I can't simplely add jquery function in the "next page" link.Because I may get some other links.
How can I stop the file downloading when I click a different link ?
Consider this form:
<form action="http://www.blabla.com?a=1&b=2" method="GET">
<input type="hidden" name="c" value="3" />
</form>
When submitting this GET form, the parameters a and b are disappearing.
Is there a reason for that?
Is there a way of avoiding this behaviour?
Isn't that what hidden parameters are for to start with...?
<form action="http://www.example.com" method="GET">
<input type="hidden" name="a" value="1" />
<input type="hidden" name="b" value="2" />
<input type="hidden" name="c" value="3" />
<input type="submit" />
</form>
I wouldn't count on any browser retaining any existing query string in the action URL.
As the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) state:
If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.
Maybe one could percent-encode the action-URL to embed the question mark and the parameters, and then cross one's fingers to hope all browsers would leave that URL as it (and validate that the server understands it too). But I'd never rely on that.
By the way: it's not different for non-hidden form fields. For POST the action URL could hold a query string though.
In HTML5, this is per-spec behaviour.
See Association of controls and forms - Form submission algorithm.
Look at "4.10.22.3 Form submission algorithm", step 17. In the case of a GET form to an http/s URI with a query string:
Let destination be a new URL that is equal to the action except that
its <query> component is replaced by query (adding a U+003F QUESTION
MARK character (?) if appropriate).
So, your browser will trash the existing "?..." part of your URI and replace it with a new one based on your form.
In HTML 4.01, the spec produces invalid URIs - most browsers didn't actually do this though...
See Forms - Processing form data, step four - the URI will have a ? appended, even if it already contains one.
What you can do is using a simple foreach on the table containing the GET information. For example in PHP :
foreach ($_GET as $key => $value) {
$key = htmlspecialchars($key);
$value = htmlspecialchars($value);
echo "<input type='hidden' name='$key' value='$value'/>";
}
As the GET values are coming from the user, we should escape them before printing on screen.
You should include the two items (a and b) as hidden input elements as well as C.
I had a very similar problem where for the form action, I had something like:
<form action="http://www.example.com/?q=content/something" method="GET">
<input type="submit" value="Go away..." />
</form>
The button would get the user to the site, but the query info disappeared so the user landed on the home page rather than the desired content page. The solution in my case was to find out how to code the URL without the query that would get the user to the desired page. In this case my target was a Drupal site, so as it turned out /content/something also worked. I also could have used a node number (i.e. /node/123).
If you need workaround, as this form can be placed in 3rd party systems, you can use Apache mod_rewrite like this:
RewriteRule ^dummy.link$ index.php?a=1&b=2 [QSA,L]
then your new form will look like this:
<form ... action="http:/www.blabla.com/dummy.link" method="GET">
<input type="hidden" name="c" value="3" />
</form>
and Apache will append 3rd parameter to query
When the original query has array, for php:
foreach (explode("\n", http_build_query($query, '', "\n")) as $keyValue) {
[$key, $value] = explode('=', $keyValue, 2);
$key = htmlspecialchars(urldecode($key), ENT_COMPAT | ENT_HTML5);
$value = htmlspecialchars(urldecode($value), ENT_COMPAT | ENT_HTML5);
echo '<input type="hidden" name="' . $key . '" value="' . $value . '"' . "/>\n";
}
To answer your first question yes the browser does that and the reason is
that the browser does not care about existing parameters in the action URL
so it removes them completely
and to prevent this from happening use this JavaScript function that I wrote
using jQuery in:
function addQueryStringAsHidden(form){
if (form.attr("action") === undefined){
throw "form does not have action attribute"
}
let url = form.attr("action");
if (url.includes("?") === false) return false;
let index = url.indexOf("?");
let action = url.slice(0, index)
let params = url.slice(index);
url = new URLSearchParams(params);
for (param of url.keys()){
let paramValue = url.get(param);
let attrObject = {"type":"hidden", "name":param, "value":paramValue};
let hidden = $("<input>").attr(attrObject);
form.append(hidden);
}
form.attr("action", action)
}
My observation
when method is GET and form is submitted, hidden input element was sent as query parmater. Old params in action url were wiped out. So basically in this case, form data is replacing query string in action url
When method is POST, and form is submitted, Query parameters in action url were intact (req.query) and input element data was sent as form data (req.body)
So short story long, if you want to pass query params as well as form data, use method attribute as "POST"
This is in response to the above post by Efx:
If the URL already contains the var you want to change, then it is added yet again as a hidden field.
Here is a modification of that code as to prevent duplicating vars in the URL:
foreach ($_GET as $key => $value) {
if ($key != "my_key") {
echo("<input type='hidden' name='$key' value='$value'/>");
}
}
Your construction is illegal. You cannot include parameters in the action value of a form. What happens if you try this is going to depend on quirks of the browser. I wouldn't be surprised if it worked with one browser and not another. Even if it appeared to work, I would not rely on it, because the next version of the browser might change the behavior.
"But lets say I have parameters in query string and in hidden inputs, what can I do?" What you can do is fix the error. Not to be snide, but this is a little like asking, "But lets say my URL uses percent signs instead of slashes, what can I do?" The only possible answer is, you can fix the URL.
I usually write something like this:
foreach($_GET as $key=>$content){
echo "<input type='hidden' name='$key' value='$content'/>";
}
This is working, but don't forget to sanitize your inputs against XSS attacks!
<form ... action="http:/www.blabla.com?a=1&b=2" method ="POST">
<input type="hidden" name="c" value="3" />
</form>
change the request method to' POST' instead of 'GET'.
I am stucked to something. In spring 2.5 framework, I want to upload file by using MultipartFile. I have a class called Dosya including property which is MultipartFile multiDosya. My command object is dosya. Additonally, The file which will be uploaded is stored BLOB type in database, sql developer,.
In jsp, I try to bind this propert like below:
<spring:bind path="dosya.multiDosya">
<input class="file" type="file" name="yuklenecekDosya" id="yuklenecekDosya" />
</spring:bind>
In onSubmit,
Dosya dosyaObjesi = (Dosya)command;
MultipartFile yuklenecekDosya = dosyaObjesi.getMultiDosya();
The commandObject dosyaObjesi is taken without problem, however,
dosyaObjesi.getMultiDosya()
value is coming null although file that will be uploaded is selected in jsp.
After searching on the net, I found that this line below should be added to the initBinder.
binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
However, my class says that there is no such class ByteArrayMultipartFileEditor, but it is available in spring-2.5.jar. I import
import org.springframework.web.multipart.*;
can trace out the problem . could someone please help me out
Thanks in advance.
Have you specified form encryption type(enctype="multipart/form-data")?. That could be the reason sometimes.
Ex:
<form method="post" name="formName" action="action.htm" commandName="object" enctype="multipart/form-data">
I have solved the problem. Everything is ok, however, in the code below
<input class="file" type="file" name="yuklenecekDosya" id="yuklenecekDosya" />
the attribute name must be ${status.expression} . That is, exactly, name="${status.expression}" like that. If only the name property value is given like that, bind operation works correctly.
Thanks,
Regards,
I put a browser in my jsp page, and when I select the file via the browser
and I'm doing a System.outn select the file path, I only have the name,
and I need to recover all the file path selected
<form:form onsubmit="document.getElementById('idButton').value='TraƮtement en cours ...'" action="ajouter.html"
method="POST">
<input type="file" name="cible">
<input type="submit" id="idButton" name="ajouter" value="Ajouter" tabindex="50"/>
</form:form>
(ActionForm)
String leChemin = (String) request.getParameter("cible");
System.out.println("leChemin = " + leChemin);
You cannot do this, for security reasons, file path from clients are not shown.
But if really need to get the path, do not rely on the browser use applet.
The path would be useless for you, none the less. Moreover, as a privacy concern, its not really a good idea to know the path at client's machine.
I have this GSP:
<g:uploadForm name="myForm" action='save'>
<input type='file' name='documentFile' value=''/>
<input type='file' name='documentFile' value=''/>
<input type='file' name='documentFile' value=''/>
<input type='file' name='documentFile' value=''/>
<input type='submit' value='Submit'/>
</g:uploadForm>
But when I tried to view the result in controller by typing:
render(params);
return true;
I got this result:
"documentFile":org.springframework.web.multipart.commons.CommonsMultipartFile#14dcf95
How do I read each file that is being uploaded?
Could I get the following?
documentFile:[File,null,File,null] // (if the 2nd and the 4th are not being used)
ps: I'm using grails 1.2.2
First, you'll need to give unique names to each of your file inputs:
<g:uploadForm name="myForm" action="save">
<input type="file" name="documentFile1" value=""/>
<input type="file" name="documentFile2" value=""/>
...
</g:uploadForm>
Then in your controller, you can use:
// access each file by name
File file = request.getFile('documentFile1')
// or iterate through them
request.fileNames.each {
File file = request.getFile(it)
}
I'm pretty sure that your name attributes have to be unique. I can't find anything in the API that will allow you to get an array of files that were uploaded with the same input name.
References:
http://www.grails.org/File+Upload
http://www.grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.1.9%20Uploading%20Files
Starting with grails 1.2 (spring 3.0), you can access multiple files from inputs with the same name (or that use the HTML5 multiple attribute) with the multiFileMap property of the controller's request object (when the request is a multipart form post, the request object will be an instance of MultipartRequest). So you can access the list of MultipartFile objects for a specific input name (ie documentFile) like this:
def save = {
List<MultipartFile> files = request.multiFileMap.documentFile
int count = files.findAll { !it.empty }.size
render "uploaded $count files"
}
Or access all MultipartFile objects from all inputs like this:
def save = {
List<MultipartFile> files = request.multiFileMap.collect { it.value }.flatten()
int count = files.findAll { !it.empty }.size
render "uploaded $count files"
}
Edit 2013-02-08: Brian Adams asks:
In above case, I can access all MultipartFile objects from all inputs
on my web page. But I wants to get files from any input is multiple.
Ex: I have input name is: "uploadFiles", and I wants get all files
from this input tag any. Can you help me?
Brian, I think what you want is the first version of the above. If your file input is named "uploadFiles", then you can access it from the multiFileMap using the "uploadFiles" key:
def save = {
List<MultipartFile> files = request.multiFileMap.uploadFiles
int count = files.findAll { !it.empty }.size
render "uploaded $count files"
}