How can I pass the value of textarea to a new page according to the groupwall method?
Here I just redirect the page. I want to make status update according to their semester.
Here is my code. Give me some code sample or suggest if this is not the right way to do that.
<form action="" method="get">
<textarea name="status" id="wall" cols="50" rows="2">
</textarea>
<input name="submit" type="submit" value="share" onclick="groupwall();"/>
</form>
<script type="text/javascript">
function groupwall(){
var semster=document.getElementById('txtsamp').value;
if(semster == "4-1"){
window.location ='4-1hpage.php';
//header("location: member-index.php");
}
else if(semster =="3-1"){
window.location ='3-1hpage.php';
}
else if(semster == "2-1"){
window.location ='2-1hpage.php';
}
else {
window.location ='1-1hpage.php';
}
}
</script>
you might be better off posting the textarea content to your server and storing it somewhere, even in the session. the reason I say this is that while you could pass it in window.location as a GET parameter, the textarea content can be arbitrarily long and might be too long to be passed as a GET parameter. you might consider an AJAX request to post the textarea to the content, perhaps performing validation, before redirecting to the next page of your application.
Just give your form an id -
<form id="share-form" ...
Set the action of the form instead of redirecting
var share_form = document.getElementById('share-form');
share_form.action = '....';
Submit the form
share_form.submit();
1) do a form post to another PHP page and
a) Store it in a database (If you will really use this in future also)
OR
b) Store it in Session Variable
OR
2) do an ajax post to a server page and
OR
a) Store it in a database
OR
b) Store it in Session Variable
Then from any PHP pages you can access these values.
Send as a parameter through the query string yoururl.com?variable=value
Through $_SESSION environment variable
Using a cookie (if turned on)
AJAX - store in database or text file before leaving page, and retrieve when entering new page
The simplest way to pass some sort of variable to a new page if the data isn't large is to put it in a query string in the URL and then have the new page parse it out of there and act on it. A query string is the part of the URL that follows a question mark like this:
4-1hpage.php?data=whatever
The query string values don't affect which page is called on your server, but can be used by either server or client to trigger different behavior in that page.
In the specifics of your particular question, it doesn't seem like you need to pass any data to the next page because you're already called a different page based on the results of the textarea, but you could pass the value like this if you needed to:
function groupwall() {
var semster=document.getElementById('txtsamp').value;
var url;
if(semster == "4-1") {
url ='4-1hpage.php';
} else if(semster =="3-1") {
url ='3-1hpage.php';
} else if(semster == "2-1") {
url ='2-1hpage.php';
} else {
url ='1-1hpage.php';
}
// encode the data for URL safety and make sure it isn't too long
window.location = url + "?semster=" + encodeURIComponent(semster.slice(0, 128));
}
If the textarea can be arbitrarily long and it needs to be capable of accepting very long values, then you will want to post it to your server and let the server decide where to redirect the user after the form post. When generating a new page, the server can then populate that page with whatever content is needed based on the values in the form post.
Other places that data can be stored temporarily so a future page can access it are cookies and HTML5 local storage. Cookies are somewhat restricted in size and it isn't efficient to put large data into cookies. HTML5 local storage isn't supported in all browsers so you generally need an alternate strategy as a fallback.
Related
I have a variable to check if the data is present already in the database.
If the data is already present it would go back to the form page to input a new data. Here is what I have
<script type="text/javascript">
window.history.back();
window.location = 'register.php?msg='<?php echo 1;?>
</script>
Also I have tried this but I don't know how to pass it in the URL:
<script type="text/javascript">
window.history.back();
window.alert('<?php $msg = 1; echo $msg;?>')
</script>
You can use History API to change the url:
history.back();
history.replaceState({}, "Registration", "register.php?msg=1");
location.reload();
You can use:
window.location = "baseurl/route?get=var"
instead of
window.history.back()
You need to be able to have baseurl as your global variable. Have it sent from your server and set in javascript as a global variable.
using browser back is fragile since you cannot predict (or check) where would that lead the user.
instead I would recommend that upon the relevant user action or business logic the app would explicitly navigate to register.php page with your desired parameter
// some code handling
var dataAlreadyPresent = checkIt();
if (dataAlreadyPresent) {
window.location = "/register.php?msg=yourMsg";
}
BTW, keep in mind that this URL is saved and users might bookmark it or forward it along, so may I suggest that the register.php server logic better not act automatically based on that input. you might want to clean the history state using replaceState (as per jcubic answer) once the register.php has loaded.
here my simple form:
<form id="myform">
Name:<input type="text" name="name"><br>
Email:<input type="text" name="email">
<a class="btn btn-primary" id="click_btn">Submit</a>
</form>
I want to submit the form with Ajax, that bit is okay so far, and submitting.
Here is my jquery code:
$(document).ready(function() {
$('#click_btn').on('click', function() {
$.ajax({
url: $('myform').attr('action'),
data: $('myform').serialize(),
method: 'post',
success: function(data) {
//success meseg then redirct
alert('success');
var data = $('#myform').serializeArray();
var dataObj = {};
$(data).each(function(i, field) {
dataObj[field.name] = field.value;
window.location.href = 'next_page.php';
});
}
})
});
})
next_page.php is where I want to access, example:
<?php echo document.write(dataObj["email"]); ?>
I want to access these form values that I have submitted on next page after the form is submitted. I have created a data object with all the values using jQuery after submit, but still, I cannot access on the next page. Is there any concept related to the session in jquery for storing that array.
I think you're getting a couple of concepts confused here; I don't mean that in a condescending way, just trying to be helpful.
jQuery, and all JavaScript, exists only on the client-side (for practical purposes - there are exceptions where some client-side code might be rendered or compiled on the server-side for whatever reason but that's another matter). PHP, like any other server-side language, exists on the server-side. These two can't directly access each other's scope - which is why AJAX is useful to transfer data between the front and back ends.
Basically what you appear to be doing here is loading the data in the client-side, but not submitting anything to the server-side. You aren't actually doing any AJAX queries. When you redirect the user via window.location.href =..., no data is actually being transmitted - it simply instructs the browser to issue a new GET request to next_page.php (or wherever you instruct it to go).
There are a couple of options to do what you're trying to achieve:
Actually submit an AJAX query, using the methods outlined here http://api.jquery.com/jquery.ajax/. You can then use next_page.php to grab the data and store it in a session and recall it when the user arrives on the page.
Store the data in a client-side cookie.
Use the standard HTML <form method="next_page.php"...><input type="submit"> to cause the browser to forward the form data to the next_page.php script.
A number of other options but I think those are the simplest.
You can totally use sessionStorage ! (Here is documentation)
If user direct to next page in same tab, sessionStorage can easily save you data and reuse in next page.
// set in page A
window.sessionStorage.setItem('youdata', 'youdata');
// or window.sessionStorage['youdata'] = 'youdata';
// get in page B
var youdata = window.sessionStorage.getItem('youdata');
// or var youdata = window.sessionStorage['youdata'];
That's it! very simple!
If you'll open a new tab, you can use localStorage. (Here is documentation)
The usage of localStorage is like the way of sessionStorage.
While do saving information for other pages, these two method only need browsers' support.
<?php echo document.write(dataObj["email"]); ?>
This is unreasoned! echo is a PHP command, but document.write is a JavaScript command.
If the secound page is PHP, why not send data with a simple POST submit from HTML Form?
You can also use localStorage:
var data = '123';
localStorage['stuff'] = data;
Use localStorage.clear(); to remove all data if you want to write it again or for specific item use localStorage.removeItem('stuff');
List of some possible solutions are as follows:
1. Post the data using AJAX request and the get it in next page by doing DB call (Advisable)
2. Using Local storage you can store the data in the browser to push it to next_page.php https://www.w3schools.com/Html/html5_webstorage.asp
2a. In the first page
<script>
localStorage.setItem("name", "John");
localStorage.setItem("email", "John#test.com");
</script>
2b. In second Page
<script>
var name = localStorage.getItem("name");
var emaeil = localStorage.getItem("email");
</script>
3. Using browser session storage https://www.w3schools.com/jsref/prop_win_sessionstorage.asp
3a. In the first page
<script>
sessionStorage.setItem("name", "John");
sessionStorage.setItem("email", "John#test.com");
</script>
3b. In second Page
<script>
var name = sessionStorage.getItem("name");
var emaeil = sessionStorage.getItem("email");
</script>
I know on client side (javascript) you can use windows.location.hash but could not find anyway to access from the server side. I'm using asp.net.
We had a situation where we needed to persist the URL hash across ASP.Net post backs. As the browser does not send the hash to the server by default, the only way to do it is to use some Javascript:
When the form submits, grab the hash (window.location.hash) and store it in a server-side hidden input field Put this in a DIV with an id of "urlhash" so we can find it easily later.
On the server you can use this value if you need to do something with it. You can even change it if you need to.
On page load on the client, check the value of this this hidden field. You will want to find it by the DIV it is contained in as the auto-generated ID won't be known. Yes, you could do some trickery here with .ClientID but we found it simpler to just use the wrapper DIV as it allows all this Javascript to live in an external file and be used in a generic fashion.
If the hidden input field has a valid value, set that as the URL hash (window.location.hash again) and/or perform other actions.
We used jQuery to simplify the selecting of the field, etc ... all in all it ends up being a few jQuery calls, one to save the value, and another to restore it.
Before submit:
$("form").submit(function() {
$("input", "#urlhash").val(window.location.hash);
});
On page load:
var hashVal = $("input", "#urlhash").val();
if (IsHashValid(hashVal)) {
window.location.hash = hashVal;
}
IsHashValid() can check for "undefined" or other things you don't want to handle.
Also, make sure you use $(document).ready() appropriately, of course.
[RFC 2396][1] section 4.1:
When a URI reference is used to perform a retrieval action on the
identified resource, the optional fragment identifier, separated from
the URI by a crosshatch ("#") character, consists of additional
reference information to be interpreted by the user agent after the
retrieval action has been successfully completed. As such, it is not
part of a URI, but is often used in conjunction with a URI.
(emphasis added)
[1]: https://www.rfc-editor.org/rfc/rfc2396#section-4
That's because the browser doesn't transmit that part to the server, sorry.
Probably the only choice is to read it on the client side and transfer it manually to the server (GET/POST/AJAX).
Regards
Artur
You may see also how to play with back button and browser history
at Malcan
Just to rule out the possibility you aren't actually trying to see the fragment on a GET/POST and actually want to know how to access that part of a URI object you have within your server-side code, it is under Uri.Fragment (MSDN docs).
Possible solution for GET requests:
New Link format: http://example.com/yourDirectory?hash=video01
Call this function toward top of controller or http://example.com/yourDirectory/index.php:
function redirect()
{
if (!empty($_GET['hash'])) {
/** Sanitize & Validate $_GET['hash']
If valid return string
If invalid: return empty or false
******************************************************/
$validHash = sanitizeAndValidateHashFunction($_GET['hash']);
if (!empty($validHash)) {
$url = './#' . $validHash;
} else {
$url = '/your404page.php';
}
header("Location: $url");
}
}
I have two subsequent forms on my website with POST method.
The first page of my website first.php contains this code:
<form action="a.php" method="POST" target="_blank">
<input name="value" type="hidden" value="foo"/>
<div class="button"><label><span class="icon"></span>
<input type="submit" class="button-graphic ajax" value="Click Here"></label></div></form>
a.php can be accessed only via this POST request (otherwise user will get method not allowed 405 error)
Once submitted, this form opens a.php with an AJAX modal window.
a.php contains another form:
<form action="b.php" method="POST" target="_blank">
<input name="bar" type="hidden" value="none"/>
<div class="border"><label><input type="submit" class="button-graphic2 tracking" value="Continue"></label></div></form>
When a user clicks Submit in the second form, it will open b.php,
which can also be accessed only via POST request (otherwise - 405 error).
The only difference I can think about between these forms is that the second one contains a tracking js class (opening an iframe). this is the js code:
$(document).ready(function() {
$(".tracking").click(function(){
var iframe = document.createElement('iframe');
iframe.style.width = '0px';
iframe.style.height = '0px';
iframe.style.display = 'block';
document.body.appendChild(iframe);
iframe.src = '/track.htm';
});
This is done in order to track a conversion using a third party script which is being execuated from track.htm
I noticed that I am having a problem with about 5% of my iPad visitors.
they open a.php properly with a POST request, but when they go ahead to continue and open b.php as well, about 5% sends out a GET request instead of the desired POST request, causing them to get an 405 error and leave the website.
I know that these are real human users as I can see some of them trying several times to open b.php and keep getting these 405 errors.
Could this be caused because simultaneously their device is using a GET request to obtain track.htm? and this is some glitch?
How can this be solved?
EDIT 4.4.2015:
Since there's a chance that firing the tracking script is causing this, I would like to know if there's another fire to fire it (or track that adwords conversion), without causing these iPad user to use "GET" requests for the form as well.
EDIT 10.4.2015:
This is the jquery code of the ajax class, that effects both first.php and perhaps a.php, as first.php is the parent frame:
$(document).ready(function() {
$(".ajax").click(function(t) {
t.preventDefault();
var e = $(this).closest("form");
return $.colorbox({
href: e.attr("action"),
transition: "elastic",
overlayClose: !1,
maxWidth: $("html").hasClass("ie7") ? "45%" : "false",
opacity: .7,
data: {
value: e.find('input[name="value"]').val(),
}
}), !1
})
}),
Technically, it shouldn't happen. The iframe created by your tracking script pointed to /track.htm, so there shouldn't be any GET request to your b.php page.
On the other hand, just thinking out loud here, there're a few scenario that could happen because of "real world" user.
The users happen to have bookmark the b.php page, thus causing them to open it using GET when they try to re-open the page using their bookmark.
The users tried to refresh the page b.php, then get warned about "Form re-submission". Being clueless as most real user are, they canceled the form re-submission, then click on the address bar and click GO on their browser with the sole intention of reloading the page. This could also cause the GET request to send to the b.php page.
Considering the best practice when designing the page flow for form submission, it might be better for you to only "process" your form data in b.php and then return a 302 Redirect to another page that show the result using a GET request. This will allow users to "refresh" the page without double submitting the form, and also allow user to bookmark the result page too.
This doesn't answer your question but as it entails to the GET glitch but as things stand, ~5% of your iPad visitors can't sign up because the code only accepts POST and so far no one can figure this out. So I propose a change of strategy, at least in the mean time.
Preventing CSRF by only accepting POST requests is already known to not work. Your choice of accepting only this request method as a means of security is what ultimately results in the 405. There are better ways.
One example of is using a CSRF token, specifically the Synchronizer Token Pattern.
The idea behind a CSRF token is that when you generate the form, you also generate a "key" which you tie to the form. When that form is submitted, if it doesn't have the key or the key isn't the right one, you don't bother processing the form. The Syncronizer Token Pattern gets fancy in that it changes the expect key each time (in the form field implementation, giving the <input type="hidden"> field a new name attribute each time) in addition to the value.
Have your code in a.php generate a random token and
store it as a session variable on the server. Output the token in the form as a hidden field.
Before processing the request in b.php, ensure the token value is in the request data and ensure it has the expected value.
You can first check for $_POST data and if it is missing, check for $_GET data. Regardless of which array contains the data, if the data does not have a valid CSRF token, respond with a 4xx error.
If the token is good, consume the token and process the request.
If the token is missing or is invalid, return a 4xx response code.
Another way would be to set your field names to random values each time the form is generated. So instead of <input name="value" type="hidden" value="foo"/> or <input name="bar" type="hidden" value="none"/>.
// ... in an importable file somewhere ...
// Generate our tokens
function token($len = 13) {
$chrs = 'abcdefghijklmnopqrstuvwxyz0123456789_';
$str = '';
$upper_lim = strlen($chrs) - 1;
for ($i = 0; $i < $len; $i++) {
$idx = rand(0, $upper_lim);
$str .= rand(0, 1) ? strtoupper($chrs[$idx]) : $chrs[$idx];
}
return $str;
}
function magic_set_function($key, $value) {
$_SESSION[$key] = $value;
}
function magic_get_function($key) {
return (array_key_exists($key, $_SESSION) ? $_SESSION[$key] : NULL)
}
function validate_request() {
$data = !empty($_POST) ? $_POST : $_GET;
if ( empty($data) ) { return false; }
// Ensure the tokens exist (hopefully not too costly)
$field_tokens = magic_get_function('field_tokens');
if ( $field_tokens) === NULL ) { return false; }
$csrf_token_name = $field_tokens['token'];
$given_csrf_token = $data[$csrf_token_name];
// Get our CSRF token
$expected_csrf_token = magic_get_function('csrf_token');
// ensure we're expecting a request / that we have generated a CSRF
if ( $expected_csrf_token === NULL ||
$expected_csrf_token !== $given_csrf_token) {
return FALSE;
}
// After whatever other checks you want...
return TRUE;
}
function fetch_data() {
$data = empty($_POST) == FALSE ? $_POST : $_GET;
if (empty($data ) { throw new DataLoadException(); }
// Ensure the tokens exist (hopefully not too costly)
$field_tokens = magic_get_function('field_tokens');
if ( $field_tokens) === NULL ) { throw new TokenLoadException(); }
foreach ($field_tokens as $field_name => $token_name) {
if ( isset($data[$token_name]) ) {
$data[$field_name] = $data[$token_name];
unset($data[$token_name]);
}
}
return $data;
}
// first.php/a.php/b.php (wherever necessary)
// ...
$tokens = array();
// our csrf token
$csrf_token = token();
$field_names = array('value', 'bar', 'token');
$field_values = array('value'=>'foo', 'bar' => 'none', 'token' => $csrf_token);
// Tokenize errthing...
foreach ($field_names as $k => $field_name) {
// and generate random strings
$tokens[$field_name] = token();
}
// You NEED TO STORE THESE TOKENS otherwise submissions lose context
magic_set_function('field_tokens', $tokens);
magic_set_function('csrf_token', $csrf_token); // dup, but j.i.c.
// first.php
printf('<input type="hidden" name="%s" value="%s"/>', $tokens['value'], $field_values['value']);
// ...
// a.php
// Get the data... (POST/GET)
if (ensure_valid_request() !== TRUE) { handle_invalid_request(); }
$data = fetch_data();
// ...
// Tokenize errthing, generate a csrf, store the values, etc.
// ...
printf('<input type="hidden" name="%s" value="%s"/>', $tokens['bar'], $field_values['bar']);
// ...
// b.php
// ... You get the idea ...
It doesn't answer your question of why 5% are sending GET Requests but it does solve your overall problem on both a security and user level.
EDIT:
To specifically answer OPs questions in comments:
"(1) does this require using cookies? (a session means cookies right?)"
Read up on PHP Sessions and look for a session library. Plenty out there, one heavyweight being Zend(http://framework.zend.com/manual/1.12/en/zend.session.html). You can save to a database instead for protected server-side sessions. I made one similar to Kohana's.
(2) I didn't understand the "another way" part - how does it differ from the method you described at first?
First method is to just add a token to your form and look for the token to have the expected value upon submission. If the form doesn't have it, you throw an error complaining.
Second method dynamically sets the field names upon form generation AND adds a token field. Submitting the proper form data from a program, bot, or outside source now first requires fetching the form since they wont know what field names to use (instead of just posting data with set field names).
"(3) most important, I am less worried about CSRF attacks, I just don't want bots/crawler to crawl into my forms, would this method prevent it from them, as opposed to humans? why? and is there an easier method to achieve that?"
If you mean bots like Google/SEO/respectful web-crawlers, robots.txt exists
for this purpose. robots.txt is a very simple text file that is placed in your site's root directory. You'll see requests in your webserver's access logs for a /robots.txt. This file tells search engine and other robots which areas of your site they are allowed to visit and index. You can read more on the (Robot Exclusion Standard)4 on many (websites)5.
As the second link notes, don't use robots.txt to hide information. It is a public file and visible to anyone. Also, malicious bots wont respect the file.
I'm not sure if when you say bots you mean just crawlers or spambots (bots trying to submit data) and such. If it's crawlers, robots.txt takes care of them. If it's spambots, you can add a hidden field (hidden with CSS not html) with a common name that when filled out you know is invalid, you can add a captcha, etc, etc, etc.
Try doing the tracking on the callback of the original request to ensure its loaded?
Also you could look into something like ajaxFormPlugin by malsup
i would like to suggest to check the permission of your "b.php" page. Please make sure the page has "w" permission for all users. this is a chance for not making a "POST" request.
I know it's a workaround but if, as I suppose, you have a bunch of checks for the $_POST variables, if you receive a GET request you could try replace the POST with the GET:
if (empty($_POST) && !empty($_GET)) $_POST = $_GET;
//here the check of $_POST
//...
since we don't know why this ipads (...apple -.-) have the issue, and between GET and POST there isn't so much difference - at least if you don't need to upload files...
The only way a post form can be sent as get is using script (changing the method attribute directly, or replacing the form behavior for example with an ajax request, binding to the event "submit" another function), so I suggest you to check every script that run in the parent and the children pages.
your ajax call doesn't contain method: "POST". This can be the cause.
I have following javascript :
var link = AjaxLocation + "/createDataSet.aspx";
$j.post(link, null, function() {
window.location.replace("/admin/SavedDataSet_edit.aspx?businessId="+data);
}, "html");
createDataSet.aspx page returns businessId for SavedDataSet_edit.aspx page...
whenever page redirect to SavedDataSet_edit.aspx page, querystring displays in the addressbar of the browser.
how to hide Querystring ?? and if i hide querystring from the browser then how to fetch it in the SavedDataSet_edit.aspx page??
Thanks..
There are a number of ways to achive that: you can use cookies(I wouldn't recommend) you can post to our page hidden field and then retrieve it using FormCollection property of the Request object. To post to your page you would need to craete dynamically a form that then submit it, the code would look like:
var link = AjaxLocation + "/createDataSet.aspx";
$j.post(link, null, function() {
$("<form action='/admin/SavedDataSet_edit.aspx'><input name='businessId' type='hidden' value='"+ data +"'></form>").appendTo('body').submit();
}, "html");
The only way to hide it is to pass it to SavedDataSet_edit.aspx, store it in session, then have that page redirect to itself without the querystring. Or use a different page in-between the two to save in session. Or, you could encrypt the value and pass encrypted querystring, provided data is a value coming from the server.
Make sure, even though you may do that, to check permissions on the resource to see that the user is authorized.
window.location.replace is not a POST request, so it cannot send POST data. So your choices are:
Keep using the query string route and just live with the value showing, sounds like this is not a realistic option though
Put the query string data into a form and submit the form as described in various answers to pass post data with window.location.href.
Leverage the AJAX call you are already making to createDataSet.aspx and store the value you want to retrieve on SavedDataSet_edit.aspx page by storing the businessId data in Session when you are in the createDataSet.aspx and then retrieving it from Session cache when you are in the Page_Load of SaveDataSet_edit.aspx.