I'm trying to write a pdf file to the browser and when the client print the pdf the filename sent to the printer is the name of the file. But now i'm getting the name of the asp page sent to the browser "loadfile.asp"
Because I can't put a title in my page when i'm using Response.ContentType = "application/pdf", I've added a page that do a server.Transfer.
But everytime the code pass trought the Response.ContentType = "application/pdf" the title get blanked.
So here's my code :
First Page :
<html>
<head>
<title>
<%= Request.QueryString("File") & ".PDF" %>
</title>
</head>
<body>
<%
Server.Transfer "loadfileAfter.asp"
%>
</body>
</html>
Here's the Second Page (loadfileAfter.asp) :
Response.ContentType = "application/pdf"
Response.AddHeader "content-disposition", "Filename=" & Request.QueryString("File") & ".PDF"
Const adTypeBinary = 1
strFilePath = "D:\" & Request.QueryString("File") & ".PDF" 'This is the path to the file on disk.
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = adTypeBinary
objStream.LoadFromFile strFilePath
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
I tought that this line would help :
Response.AddHeader "content-disposition", "Filename=" & Request.QueryString("File") & ".PDF"
But it did not change a thing.
Thanks for your help
This one worked for me:
Response.AddHeader "content-disposition", "attachment; filename=""" & fileName & """"
Related
I am trying to stream a file to the browser using adodb.
The user gets an option like this:
The Save File option works as expected.
But the Open with Firefox option gives gobbledy, and .htm is appended to the end of the filename.
I presumed that this had to do with the setting for Response.ContentType.
I have tried using application/pdf, application/octet-stream and application/x-unknown. But whichever I use, I always get the same result.
What is going on here? What ContentType should I be using?
Shot of Open With Firefox
ADODB Stream Code
Dim objStream
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 1
objStream.Open
objStream.LoadFromFile(fileDirectory & "\" & fileToDownload)
Response.AddHeader "Expires", "0"
Response.AddHeader "Content-Transfer-Encoding", "binary"
Response.AddHeader "Content-Description", "File Transfer"
Response.AddHeader "Content-Disposition", "attachment; filename=" & fileToDownload
Response.AddHeader "Content-Length", objStream.Size
Response.CharSet = "UTF-8"
Response.ContentType = "???" // *** what should I put here? ***
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
As well as having Response.ContentType = "application/pdf", I also needed to have Response.AddHeader "Content-Type", "application/pdf".
So the final code, that worked, was:
Dim objStream
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 1 'adTypeBinary
objStream.Open
objStream.LoadFromFile(fileDirectory & "\" & fileToDownload)
Response.AddHeader "Expires", "0"
Response.AddHeader "Content-Transfer-Encoding", "binary"
Response.AddHeader "Content-Description", "File Transfer"
Response.AddHeader "Content-Disposition", "attachment; filename=" & fileToDownload
Response.AddHeader "Content-Length", objStream.Size
Response.AddHeader "Content-Type", "application/pdf" '** added this line **
Response.CharSet = "UTF-8"
Response.ContentType = "application/pdf"
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
I created a protected area in my website, where only registered users can logon to download a restricted application (exe). But they can copy the download link and make it available on internet, so I am trying to find the simplest way to hide the download link (using ASP classic, if possible).
Here is what I got so far: http://forums.aspfree.com/code-bank-54/download-manager-downloading-files-secure-location-classic-asp-65239.html. But when using this download manager, the exe application unexplainably looses its digital signing :(
Please, can anyone give me some ideas? Maybe using PHP or Flash?
Thanks!
Here is the solution I found, using ASP classic:
<%
Option Explicit
Response.Buffer = True
If (not Session("Logged")) Then Response.End
Dim objFso
Dim objStream
Dim strFileName
Dim strFilePath
strFileName = "App.exe"
strFilePath = "d:\yoursitefolder\protectedfolder\"
Set objFso = Server.CreateObject("Scripting.FileSystemObject")
If objFso.FileExists(strFilePath & strFileName) Then
Response.AddHeader "Content-disposition", "filename=" & strFileName
Response.ContentType = "application/octet-stream"
Response.AddHeader "Pragma", "no-cache"
Response.AddHeader "Expires", "0"
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 1
objStream.Open
objStream.LoadFromFile strFilePath & strFileName
Response.BinaryWrite(objStream.Read())
objStream.Close
Set objStream = Nothing
End If
Set objFso = Nothing
%>
I have a website written in Classic ASP
One page creates a .CSV file from a SQL database and stores it in the root directory along with a "Click Here" link to download it to the users PC
It has been working fine for many years and is still working fine when downloading small files, but now it comes up with a "THIS PAGE CAN'T BE DISPLAYED" error when downloading a .csv file (in this example) of some 785 records
The code is pretty short as below with the one Private Sub that does the download
<%#Language="VBScript"%>
<%Reponse.Buffer = True%>
<%
On Error Resume Next
Dim strPath
strPath = CStr(Request.QueryString("File"))
'-- do some basic error checking for the QueryString
If strPath = "" Then
Response.Clear
Response.Write("No file specified.")
Response.End
ElseIf InStr(strPath, "..") > 0 Then
Response.Clear
Response.Write("Illegal folder location.")
Response.End
ElseIf Len(strPath) > 1024 Then
Response.Clear
Response.Write("Folder path too long.")
Response.End
Else
Call DownloadFile(strPath)
End If
Private Sub DownloadFile(file)
'--declare variables
Dim strAbsFile
Dim strFileExtension
Dim objFSO
Dim objFile
Dim objStream
'-- set absolute file location
strAbsFile = Server.MapPath(file)
'-- create FSO object to check if file exists and get properties
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
'-- check to see if the file exists
If objFSO.FileExists(strAbsFile) Then
Set objFile = objFSO.GetFile(strAbsFile)
'-- first clear the response, and then set the appropriate headers
Response.Clear
'-- the filename you give it will be the one that is shown
' to the users by default when they save
Response.AddHeader "Content-Disposition", "attachment; filename=" & objFile.Name
Response.AddHeader "Content-Length", objFile.Size
Response.ContentType = "application/octet-stream"
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
'-- set as binary
objStream.Type = 1
Response.CharSet = "UTF-8"
'-- load into the stream the file
objStream.LoadFromFile(strAbsFile)
'-- send the stream in the response
Response.BinaryWrite(objStream.Read)
objStream.Close
Set objStream = Nothing
Set objFile = Nothing
Else 'objFSO.FileExists(strAbsFile)
Response.Clear
Response.Write("No such file exists.")
End If
Set objFSO = Nothing
End Sub
%>
So something has changed in recent months
Ay advice much appreciated
Thanks in advance
Your IIS version and configuration might be needed to help but I know IIS6 introduced a 4MB limit to BinaryWrite. Try sending your file in chunks instead.
<% Response.Buffer = False %>
...
With Server.CreateObject("ADODB.Stream")
.Open
.Type = 1
.LoadFromFile strPath
' Send 256K chunks...
Const intChunkSize = 262144
Do While Response.IsClientConnected And (.Position < .Size)
Response.BinaryWrite .Read(intChunkSize)
Loop
.Close
End With
I'm creating a download manager, and everything seems to work. But the file that I get downloaded can not be opened. The file has the correct name and the extension .pdf - but my Mac says that the file cannot be opened (the file on the server works).
if request.querystring("downloadFile") <> "" then
strFilePath = Server.MapPath("/_customerFiles/"& session("URLmapping") &"/documents/"& request.querystring("downloadFile"))
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFilePath) Then
Set objFile = objFSO.GetFile(strFilePath)
intFileSize = objFile.Size
Set objFile = Nothing
strFileName = request.querystring("filename")
strFileName = replace(request.querystring("downloadFile")," ","-")
Response.AddHeader "Content-Disposition","attachment; filename=" & strFileName
Response.ContentType = "application/octet-stream"
Response.AddHeader "Content-Length", intFileSize
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1 'adTypeBinary '
objStream.LoadFromFile strFilePath
Do While Not objStream.EOS And Response.IsClientConnected
Response.BinaryWrite objStream.Read(1024)
Response.Flush()
Loop
objStream.Close
Set objStream = Nothing
End if
Set objFSO = Nothing
end if
Have you considered that the output stream is having a Byte Order Mark (BOM) added (or maybe removed)? I would open both files in a hex editor and look for 3 bytes added at the start (and everything else moved along).
I know I'm late getting to this question, but I was just dealing with something similar and wanted share my observations to try to clear it up.
I have read (sorry I dont have a source) that the ADODB.Stream has to have its .Type specified prior to calling .Open
I also set the Stream .Mode property to 3 (meaning "open file for Reading") to prevent file access lock errors if multiple people try to access the file at the same time -- Also must be done before calling .Open
I have had varying success with Response.ContentType "application/octet-stream", and after some problems there, I changed mine to Response.ContentType "xxx/xxx". The browser will accept it as an unknown file type and then prompt the user to open it based on the registered program for that file extension.
Before you start adding Response Headers, you should call Response.Clear (just to be sure you're not sending extra markup)
After closing your FileSystemObject, you should call Response.End (again, just to be sure)
You needs to add the Response.Clear before Response.AddHeader and change the Response.ContentType, so the code is like below:
if request.querystring("downloadFile") <> "" then
strFilePath = Server.MapPath("/_customerFiles/"& session("URLmapping") &"/documents/"& request.querystring("downloadFile"))
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFilePath) Then
Set objFile = objFSO.GetFile(strFilePath)
intFileSize = objFile.Size
Set objFile = Nothing
strFileName = request.querystring("filename")
strFileName = replace(request.querystring("downloadFile")," ","-")
Response.Clear
Response.AddHeader "Content-Disposition","attachment; filename=" & strFileName
Response.ContentType = "xxx/xxx"
Response.AddHeader "Content-Length", intFileSize
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1 'adTypeBinary '
objStream.LoadFromFile strFilePath
Do While Not objStream.EOS And Response.IsClientConnected
Response.BinaryWrite objStream.Read(1024)
Response.Flush()
Loop
objStream.Close
Set objStream = Nothing
End if
Set objFSO = Nothing
End if
I am working on Classic Asp with VBScript. I am trying to display list of files from a directory with download option. like,
When i click on the download link the corresponding file need to be download for that i have used the following code like,
<html>
<head>
<title> My First ASP Page </title>
</head>
<body>
<%
Dim fso
Dim ObjFolder
Dim ObjOutFile
Dim ObjFiles
Dim ObjFile
'Creating File System Object
Set fso = CreateObject("Scripting.FileSystemObject")
'Getting the Folder Object
Set ObjFolder = fso.GetFolder("F:\karthik")
'Creating an Output File to write the File Names
Set ObjOutFile = fso.CreateTextFile("F:\WindowsFiles.txt")
'Getting the list of Files
Set ObjFiles = ObjFolder.Files
'Writing Name and Path of each File to Output File
Response.Write("<table cellpadding=""4"" cellspacing=""5"" >")
For Each ObjFile In ObjFiles
Response.Write("<tr><td>"&ObjFile.Name & String(50 - Len(ObjFile.Name), " ")&"</td><td>Download</td></tr>")
Next
Response.Write("</table>")
ObjOutFile.Close
%><br>
<script language="vbscript" type="text/vbscript">
Sub HTTPDownload( myURL, myPath )
' Standard housekeeping
Dim i, objFile, objFSO, objHTTP, strFile, strMsg
Const ForReading = 1, ForWriting = 2, ForAppending = 8
' Create a File System Object
Set objFSO = CreateObject( "Scripting.FileSystemObject" )
' Check if the specified target file or folder exists,
' and build the fully qualified path of the target file
If objFSO.FolderExists( myPath ) Then
strFile = objFSO.BuildPath( myPath, Mid( myURL, InStrRev( myURL, "/" ) + 1 ) )
ElseIf objFSO.FolderExists( Left( myPath, InStrRev( myPath, "\" ) - 1 ) ) Then
strFile = myPath
Else
WScript.Echo "ERROR: Target folder not found."
Exit Sub
End If
' Create or open the target file
Set objFile = objFSO.OpenTextFile( strFile, ForWriting, True )
' Create an HTTP object
Set objHTTP = CreateObject( "WinHttp.WinHttpRequest.5.1" )
' Download the specified URL
objHTTP.Open "GET", myURL, False
objHTTP.Send
' Write the downloaded byte stream to the target file
For i = 1 To LenB( objHTTP.ResponseBody )
objFile.Write Chr( AscB( MidB( objHTTP.ResponseBody, i, 1 ) ) )
Next
' Close the target file
objFile.Close( )
End Sub
</script>
</body>
</html>
It seems you are trying to do this on the server-side using client-side scripting. Here is a better solution that uses server-side ASP to send the file. You will need to split your code over two pages.
Your current script should be replaced with this:
<html>
<head>
<title> My First ASP Page </title>
</head>
<body>
<% Dim fso
Dim ObjFolder
Dim ObjOutFile
Dim ObjFiles
Dim ObjFile
'Creating File System Object
Set fso = CreateObject("Scripting.FileSystemObject")
'Getting the Folder Object
Set ObjFolder = fso.GetFolder("F:\karthik")
'Getting the list of Files
Set ObjFiles = ObjFolder.Files
'Writing Name and Path of each File to Output File
Response.Write("<table cellpadding=""4"" cellspacing=""5"" >")
For Each ObjFile In ObjFiles
Response.Write("<tr><td>"&ObjFile.Name & String(50 - Len(ObjFile.Name), " ")&"</td><td>Download</td></tr>")
Next
Response.Write("</table>")
%><br>
</body>
</html>
Then you need to create another script which I have called download.asp which handles the download:
<%
Dim objConn, strFile
Dim intCampaignRecipientID
strFile = Request.QueryString("file")
If strFile <> "" Then
Response.Buffer = False
Dim objStream
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 1 'adTypeBinary
objStream.Open
objStream.LoadFromFile("F:\karthik\" & strFile)
Response.ContentType = "application/x-unknown"
Response.Addheader "Content-Disposition", "attachment; filename=" & strFile
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
End If
%>
I like this solution, but users can see the downloads in the history, or modify the querystring. This solution can be modified for POST usage this way:
in the page code modify the link:
FileName`
and further down
<form id="frm2dl" action="download.asp" method="post"><input type="hidden" id="file2dl" name="file2dl" value="" /></form>
then in your javascript file get the filename:
function getfile(obj) {
var f=obj.innerText;
$("#frm2dl #file2dl").val(f);
$("#frm2dl").submit();
}
alternately you could use a file ID then in the download.asp have a lookup function from ID to filename.
Then in the download.asp use request.form("file2dl") instead of request.querystring.
UPDATE:
Also, depending on server version you might get the 4MB limit (I have to work with Microsoft-IIS/7.5 on intranet). Therefore for large files the code will not work. Here is my improved version:
Dim strFileName, strFilePath, objFSO, objStream, objFile, intFileSize
Const lChkSize = 524288 ' 500KB - server typical limit is 4MB
'If session("loggedIn") = True Then ' insert your logon validation code here. bypassed for testing
strFileName = request.form("file2dl")
strFilename = Replace(strFilename,"..","") ' prevent parent path navigation - also ensure uploaded files do not contain this sequence
strFilename = Replace(strFilename,"/","") ' prevent path navigation
strFilename = Replace(strFilename,"\","") ' filenames should already be cleaned by a previous process
strFilePath = server.MapPath("/insert your URL absolute sources filepath here/" & strFilename)
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFilePath) Then
Set objFile = objFSO.GetFile(strFilePath)
intFileSize = objFile.Size
Set objFile = Nothing
Response.AddHeader "Content-Disposition","attachment; filename=" & strFileName
Response.ContentType = "application/x-msdownload"
Response.AddHeader "Content-Length", intFileSize
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = 1 'adTypeBinary
objStream.Open
objStream.LoadFromFile strFilePath
Do While Not objStream.EOS And Response.IsClientConnected
Response.BinaryWrite objStream.Read(lChkSize)
Response.Flush()
Loop
objStream.Close
Set objStream = Nothing
Else
Response.write "Error finding file: " & request.form("file2dl")
End if
Set objFSO = Nothing
'End If