Link to home
Start Free TrialLog in
Avatar of thenelson
thenelson

asked on

Safari posting url code

I have several forms on my website that upload to a php script. This is working fine except when some users using the Safari browser submit the form, I am receiving url coded text as below:
...DCMedName8=&DCMedDose8=&DCMedFreq8=&DCMedStart8=&DCMedStop8=&DCMedsReason8=&formname=%2FUF%28%2FIntakeQuestionnaireSection4.txt%29

instead of standard text as below:
DCMedName8=
DCMedDose8=
DCMedFreq8=
DCMedStart8=
DCMedStop8=
DCMedsReason8=
formname=/UF(/IntakeQuestionnaireSection4.txt)

I have placed code in my url script to address this and convert the code but can someone tell me why this is happening and is there an easy way to resolve it?  TIA
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

That looks perfectly normal to me since browsers automatically URLencode form data when it is submitted.  The only question to me is why isn't your web server automatically decoding it like it does for every other browser.  We need a link and a complete copy of the query string.  Because there is nothing obviously wrong with what you have posted.
Avatar of thenelson
thenelson

ASKER

Here is a link to a copy of one of the forms. (I copied the form because the last time I posted a live link to a form on EE, I got submissions for months and occasionally still do. I will delete this form after I close this question.)
Sample Profile form

I can't send a complete copy of the query string as it contains protected health information. If you submit the form using Safari and I receive it URLencoded, I will copy it here.
Something is strange here (besides the appearance that the HTML document was created in Word).  I used View Source and looked for DCMedName8, but it was not found in the document.

You should not have to use URLDecode() on request variables since they are decoded before they are presented to your script.

Try removing the enctype declaration in the form tag (line 197).  That seems to be problematic from a quick scan of the literature.  
https://bugs.php.net/bug.php?id=33741
Note that the names in the error message from you validation script do not match the names on the form.  That can be confusing for people to try to figure out what you mean.
I copied your form and put it on my server here.  I changed it to post to my 'postdump.php' program which shows me everything that is sent.  It didn't do anything until I removed the 'enctype'.  Then it worked fine on Firefox on Windows XP and Safari on Mac OSX 10.6.8.
Dave: Yep, it's Antipractice #1 -- installing the code without understanding the code!
But Ray!!!!  We'd have to shut down half the internet!!!
So I removed
enctype="text/plain"

and now I get the URL coding when I submit the form from Chrome:
Last_Name=Hochberg&First_Name=Nelson&Middle_Initial=D&Address=999+E.+Pond+Pkwy&DOI=&City=Flagstaff&State=AZ&Zip=86001&Home_Phone=928-699-8888&Work_Phone=928-699-8888&Cell_Phone=&Email=nelsonh@nosuffering.com&Password=nelsonh@nosuffering.&Sex=Male&DOB=06/01/1999&Soc_Sec_No=333-33-3333&Occupation=&Spouses_Name=Nelson+Hochberg&Referring_Provider=AZ&Reason_seeing_Doctor=test&Pharmacy_Name=Nelson+Hochberg&Pharmacy_City=Flagstaff&Pharmacy_Location=Flagstaff&Other_Docs=333+E.+Pond+Pkwy&Emergency_Contact=Nelson+Hochberg&Emergency_Relation=self&Emergency_Phone=928-699-8350&NearName=Nelson+Hochberg&NearRelation=&NearPhone=928-699-8888&NearAddress=888+E.+Pond+Pkwy&Employer_Name=Nelson+Hochberg&Employer_Phone=928-699-9999&Employer_Address=999+E.+Pond+Pkwy&Employer_City=Flagstaff&Employer_State=AZ&Employer_Zip=86001&RespName=&RespRelation=&RespAddress=999+E.+Pond+Pkwy&RespCity=Flagstaff&RespState=AZ&RespZip=86001&RespHome=&RespWork=&RespCell=&PriName=&PriPhone=928-699-8888&PriInsured=Nelson+Hochberg&PriRelation=&PriDOB=06/01/1999&PriSSN=333-33-3333&PriCopay=&PriID=&PriGroup=Nelson+Hochberg&PriMem=&SecName=&SecPhone=928-699-3333&SecInsured=Nelson+Hochberg&SecRelation=&SecDOB=06/01/1999&SecSSN=333-33-3333&SecCopay=&SecID=&SecGroup=Nelson+Hochberg&SecMember=&Signature=nelson&Date=11/15/13&formname=/UF(/PatientProfile.txt)

Open in new window

SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>Do you get consistent inputs from browsers that submit the forms?
Yes except an occasional problem with Safari: maybe one form submission in 200.

>ditch Microsoft Word in favor of writing the HTML through a standard text editor.
Creating a nice looking form using a standard text editor takes weeks of coding and I have not found a WYSIWYG html editor I can afford that will do the job.  Also, I already had the forms designed in Word.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
To understand what is going on, I modified Dave's postdump.php routine. My php routine uses file_get_contents('php://input') so I added that and I also added var_dump($_REQUEST) to better understand these php superglobals. Here is my modified postdump.php routine:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>POST Dump</title>
</head>
<body>
<pre>
<?php 
echo "REQUEST:<br>";
var_dump($_REQUEST);
echo "<br><br>file_get_contents('php://input'):<br>";
echo file_get_contents('php://input');
echo "<br><br>POST<br>";
var_dump($_POST);
echo "<br><br>";
foreach($_POST as $key => $value) {
    echo $key.'='.$value."\r\n";
}
echo "<br><br>";
echo $_POST["First_Name"]."<br>";
echo $_POST["Last_Name"]."<br>";
echo $_POST["formname"]."<br>";
?>
</pre>
</body>
</html>

Open in new window

I then created two html pages with forms: one with enctype="text/plain": profile with enctype and one without enctype="text/plain": profile no enctype. You can try these links to see the results.

What I found out is using file_get_contents('php://input') with enctype="text/plain" lists each field on a line separated by a line feed/carriage return combination but some browsers (Safari) send the url encoded string instead.

I am guessing using foreach($_POST as $key => $value) {echo $key.'='.$value."\r\n";} would give me the same format as the php://input, enctype="text/plain" but will work on all browsers. I don't have an Apple with Safari to test this out so I would appreciate some feedback.

So I am planning to write a new php routine to use the $_POST superglobal and remove the enctype="text/plain".
... use the $_POST superglobal and remove the enctype="text/plain".
That is exactly what the professionals would recommend!

You can learn more about how to use PHP in this article and this tutorial (see: "Dealing with Forms").
So I wrote a new php script to save the form post to a file using the $_POST superglobal. I tested it on Chrome, FF and IE but don't have Safari running on an Apple. I would appreciate if you all could test it if you have Safari running on Apple.  Here it is: Profile form to file.

As time permits, I will rewrite the html forms I created using MS Word.
Note that ALL browsers send the url encoded string.  That is part of the standard for sending form data.  And ALL servers are supposed to decode it.  The question is why you are not seeing it decoded sometimes.

PS: I've submitted a test form thru Safari on Mac for you.
Dave,

Well, I found out is using file_get_contents('php://input') with enctype="text/plain" lists each field on a line separated by a line feed/carriage return combination but some browsers (Safari) send the url encoded string instead.

So I changed my php script to use the foreach code you suggested. I had to add stripslashes. I have already had someone post a form from an Apple computer using Safari and it uploaded correctly.

Ray,
When I get time, I am going to use a text editor to rewrite my forms without MS Word.

Thanks to both of you.
Note to anyone reading this in the future, the correct answer, with links to the learning resources, is available here.  It is unwise (and may even present a security risk) to use file_get_contents() against 'php://input' so please don't do that.
Ray,
I am trying to understand dealing with form submission.
Why is it unwise to use file_get_contents() against 'php://input'?
How may even present a security risk?

I got the code for file_get_contents('php://input') from a website explaining how to capture the fdf data from a pdf form.
I'd like you to put the last version back up so I can capture the POST data from my browser and show you what gets sent.

'php://input' could be anything because it isn't necessarily filtered to be the form data.
Not sure which one is the "last version" you mention, so I'll try this one: Profile to file
Here are the results.  Request header comes first, the post data is last, and then the Response header.  Note that the post data is one long line with no \r\n.
barnwell-headers.txt
Thanks for the info. It was useful. How do you get the data the browser sends out? I am curious what is sent with enctype="text/plain" in the form spec. Here is the webpage with that in the form: PatientProfile W/enctype
I use a Firefox add-on called LiveHTTP Headers.

You can see in this file that the format for 'text/plain' is actually formatted wrong.
barnwell-headers-plain.txt
I would not say that is wrong. I would say that is formatted text/plain. The same format that notepad uses. It is the format I want except Safari still sends the file in URL encoded. By using the foreach code you gave me, I now convert the array that my server creates from the URL encoded string to the text/plain format eliminating the Safari problem.

Thanks again.
Well, PHP and several other languages say that is wrong and that it should be the URL encoded version in the other posting.  The reason it is wrong is because it does not show the name/value pairs in the way that the software is expecting.

But if you just want to "do it your own way", you can.  You will find that not every browser or server supports your viewpoint while they do support the URLencoded version.  I will never use the "text/plain" version, especially after this question, because of the problems that you have run into.  And, of course, because I don't use "text/plain", I have never run into this problem in the hundreds of forms that people have hired me to do.
I am not trying to be obstinate and "do it my own way". I just discovered with help from you and Ray that Chrome, FF and IE all send text/plain text as in notepad but Safari sends full URL encoded text. Both of these do not match the specification for example from w3schools.com: "Spaces are converted to "+" symbols, but no special characters are encoded". Because all the browsers do not match on the specification for enctype="text/plain", I will never use it again and I will recommend others to not use it. Further I can explain why. I have you and Ray to thank for my understanding and I thank both of you again.
I misunderstood your comment then.  Good and thanks for the points.
Dave, Ray,
I ran into a different problem using the new php script.
I would appreciate you two looking at the question: https://www.experts-exchange.com/questions/28305093/foreach-POST-as-key-value-not-getting-every-key.html
Thanks
Nelson