I have written a little survey using Python and CGI. I am trying to show a picture using the normal <img> tag, But even-though the picture is in the same directory as my cgi script, my script cannot show it. I also changed the header to this:
print "Content-type: text/html; image/jpeg"
print
print """<html>
<head>
<title>You are going to be redirected</title>
</head>
<body bgcolor = #14b585>
<br>
<p align=center><font>Helloooo</font></p>
<img src="cat.jpeg" alt="cat" width="304" height="228"/>
<form action="./sample.py" method="post">
<p align=center><input type="submit" value="YES!" /></p>
</form>
</body>
</html>
"""
Why?(it is a very small jpg file)
print "Content-type: text/html; image/jpeg"
Don't change the header to that. You can't have multiple content types for a single document (multipart documents excluded, but browsers don't support them and that isn't the right format).
You are delivering an HTML document with an reference to an image in it. The image will be a separate request and response.
print "Content-type: text/html"
Or, better:
print "Content-type: text/html; charset=utf-8"
(Assuming you are using utf-8, which you should be).
print """<html>
Your Doctype is missing. This will trigger quirks mode, which is undesirable. You also have a great deal of legacy presentational markup that should be replaced by CSS.
<img src="cat.jpeg" alt="cat" width="304" height="228"/>
The context suggests that the image is decorative, so the alternative text should probably be "" (see Alt texts in IMGS), but there is nothing wrong with the actual reference to the image.
But even-though the picture is in the same directory as my cgi script
Since the HTML seems to be OK. You need to check that the image is.
Can you reach the image by typing the URL in directly?
What do the web server logs say when you try?
It is possible that your server is configured to try to treat everything in the directory as an executable, no matter what the file extension, so it might be trying to run the image as if it were a CGI program (which will obviously fail). If so, then you could either move the image or change the configuration of the server.
And I've just noticed this comment:
I did this in my browser: localhost/cgi-bin/cat.jpg and it got an error, I checked the logs, it Exec format error: exec of '/home/hossein/public_html/cgi-bin/cat.jpg' failed
That is what is happening. Moving the image is the simplest solution.
your apache was configured to use the cgi-bin directory as an CGI scripts folder, so any request that trying to get a file from this folder apache try to execute it as an CGI script. to make your image visible move it to the www/html folder.
Related
I found this CGI Module, its letting me use HTML tags inside a python script.
ive seen some topics in here that shows how to use it, but when im using it it doesnt works.
import cgi
print ("""
<html>
<body>
Hello
</body>
</html>
""")
and this is the output when im running the script:
<html>
<body>
Hello
</body>
</html>
how can i use this properly?
thanks.
If you have your CGI script already hooked up to a web server, you will need to emit the HTTP headers too, e.g.
print("Content-Type: text/html") # HTML is following
print() # blank line, end of headers
print ("""
<html>
<body>
Hello
</body>
</html>
""")
Note that the cgi module is not being used in any way to achieve this; just simple calls to print(). The module is useful when you want to process form data submitted by a client through a HTML form.
I am trying to design and implement a basic calculator in HTML and Python(using CGI). Below given is a static HTML web page and it is being redirected to a python script (calci.py) where, I am able to calculate the sum but unable to append the resultant to the 'output' textbox.
calculator.html
<html>
<head>
<title>Calculator</title>
</head>
<body>
<form action="python_scripts/calci.py" method="post">
Input 1 : <input type="text" name="input1"/><br>
Input 2 : <input type="text" name="input2"/><br>
<input type="submit" value="+" title="add" /><br>
output : <input type="text" name="output"/><br>
</form>
</body>
</html>
calci.py
import cgi
form = cgi.FieldStorage()
input1 = form.getvalue('input1')
input2 = form.getvalue('input2')
output = str(int(input1)+int(input2))
#how to return the response to the html
#and append it to the textbox
Thanks
This is not the way Web applications work - not hat simply, at least.
If you want to rely only on the browser, and plain HTML for your application, each request has to send the whole html page as a string. You have to use Python's string formatting capabilities to put the resulting number in the correct place in the HTML form.
This way of working is typical of "Web 1.0" applications (as opposed to the "Web 2.0" term used about ten years ago).
Modern web applications use logic that runs on the client side, in Javascript code, to make an HTTP request to retrieve only the needed data - and them, this client-side logic would place your result in the proper place in the page, without reloading the page. This is what isgenerally known as "ajax". It is not that complex, but the html + javascript side of the application become much more complex.
I think one should really understand the "Web 1.0" way before doing it the "Ajax way". in your case, let's suppose your HTML containing the calculator form is in a file called "calc.html". Inside it, where the result should lie, put a markup that can be understood by Python's built-in native string formatting methods, like {result} -
<html>
<body>
...
calculator body
...
Answer: <input type="text" readonly="true" value={result} />
</body>
</html>
And rewrite your code like:
import cgi
form = cgi.FieldStorage()
input1 = form.getvalue('input1')
input2 = form.getvalue('input2')
result = int(input1)+int(input2)
html = open("calc.html".read())
header = "Content-Type: text/html; charset=UTF-8\n\n"
output = header + html.format(result=result)
print (output)
The CGI way is outdated, but is nice for learning: it relies on your whole program being run, and whatever it prints to the standard output to be redirected to the HTTP request as a response. That includes the HTTP Headers, which are included, in a minimal form, above.
(I will leave the complete implementation of a way for the raw '{result}' string not to show up in the inital calculator form as an exercise from where you are 0- the path is to get the initial calculator html template through a CGI script as well, instead of statically, (maybe the same) as well - and just populate "result" with "0" or an empty string)
you can transfer response with the help of java script.
use under print("window.location=url")
I am in the process of creating a Django web application that reads a URL and outputs selected data from the page. I have written the code in Python that parses the web page and it currently returns the information that I need to display in the Django app as desired.
Before I dive in I just want to confirm what I have researched is correct as I only have a limited time to complete the project.
To summarise my python code, it is in the src folder in a class called "manage.py"
I have created print statements that print the information that I need to display (I did this to ensure it was returning the correct data)
print(variable1)
print("some text" + variable2)
Can I create the Django app code in the same file, "manage.py"? (The project has already been created as a Django app in Eclipse when I started building the project)
Would I build the Django code as I've estimated below if I'm using the variables defined from the Python code above?
<!DOCTYPE>
<html>
<head>
<title>{% block title %}Title of website{% endblock %}</title>
</head>
<body>
<h1>Web page report</h1>
<h2>Summary of web page</h2>
<h3>Title of document</h3>
<p>{{variable1}}</p>
<h3>The file size of the document</h3>
<p>{"Some text" + {variable2}}</p>
</body>
</html>
Django has strict rules about where to place which information. You can not write everything into manage.py. Answering requests from the browser is for example done using view functions.
I am building a simple web app (posted part of it yesterday) but I am struggling with a portion:
1) Request a text file to upload
2) Save the uploaded file to a directory
I am using python and cgi for this. cgi is working as confirmed with a simple test.cgi file.
Here is my current code for request_input.cgi:
#!/usr/bin/python
import cgi
print "Content-type: text/html\r\n\r\n"
print '<html>'
print '<body>'
print '<form enctype="multipart/form-data" action="save_input.cgi" method="post">'
print '<p>File: <input type="file" name="filename" /></p>'
print '<p>input type="submit" value="Upload" /></p>'
print '</form>'
print '</body>'
print '</html>'
Now when I tail the apache error log I get the following errors:
"(2)No such file or directory: exec of '/var/www/ipcheck/request_input.cgi' failed, referer: [http://192.168.3.77/ipcheck/?C=M;O=A]"
"Premature end of script headers: request_input.cgi, referer [http://192.168.3.77/ipcheck/?C=M;O=A]"
Any help would be awesome! Thanks a lot
dos2unix resolved issue. Built in windows, moved to linux. Thanks for the help.
I simply copied all of the code in the file, opened a new python window, pasted the code into it and saved it under the same name (to overwrite the old file). Hope this helps!
I really searched about 50 related pages but never seen a problem similar to my problem. When I press the submit button, it calls the script but the script returns an empty page and I see no file was uploaded. There is no typing error in my codes, I checked it several times and I really need this code running for my project. What might be the problem? I am running apache under ubuntu and my codes are:
html code:
<html><body>
<form enctype="multipart/form-data" action="save_file.py" method="post">
<p>File: <input type="file" name="file"></p>
<p><input type="submit" value="Upload"></p>
</form>
</body></html>
python code:
#!/usr/bin/env python
import cgi, os
import cgitb; cgitb.enable()
try: #windows needs stdio set for binary mode
import msvcrt
msvcrt.setmode (0, os.O_BINARY)
msvcrt.setmode (1, os.O_BINARY)
except ImportError:
pass
form = cgi.FieldStorage()
#nested FieldStorage instance holds the file
fileitem = form['file']
#if file is uploaded
if fileitem.filename:
#strip leading path from filename to avoid directory based attacks
fn = os.path.basename(fileitem.filename)
open('/files' + fn, 'wb').write(fileitem.file.read())
message = 'The file "' + fn + '" was uploaded successfully'
else:
message = 'No file was uploaded'
print """\
Content-Type: text/html\n
<html><body>
<p>%s</p>
</body></html>
""" % (message,)
I just tested your script, with a few small corrections to the paths to make it work for me locally. With the paths set correctly, and permissions set properly, this code does work fine.
Here are the things to make sure of:
In your html file's form properties, make sure you are pointing to the python script that lives in a cgi-bin: action="/cgi-bin/save_file.py". For me, I have a cgi-bin at the root of my web server, and I placed the python script there. It will not work if you are running the script from a standard document location on the web server
Make sure your save_file.py has executable permissions: chmod 755 save_file.py
In your save_file.py, ensure that you are building a valid path to open the file for saving. I made mine absolute just for testing purposes, but something like this: open(os.path.join('/path/to/upload/files', fn)
With those points set correctly, you should not have any problems.