Данная статья раскрывает процесс организации web-интерфейса почтовой службы корпоративного интернет-сайта. Решение данной проблемы представляет из себя более сложную и интересную задачу, посмотрите пример ее реализации.
Для создания web-интерфейса имелись следующие ресурсы:
- Почтовый сервер на базе Unix
- Web сервер IIS 4.0 на базе NT Server 4.0
- MS SQL 7.0
Так как уже был создан почтовый сервер на базе Unix для домена, в котором находиться сайт нашей компании, то очевидно следующее решение задачи:
- необходима ActiveX-компонента, работающая по POP3 протоколу с почтовым сервером для приема писем с почтового ящика
- необходима ActiveX-компонента, работающая по SMTP протоколу для отсылки писем
- необходима ActiveX-компонента, загружающая файлы на Web-сервер для отсылки почты
Причем необходимое условие для этих компонент - их бесплатность.
Для приема почты я использовал компоненту JMAILс сайта http://tech.dimac.net, для отправки почты и загрузки файлов - компоненты сайта http://www.dundas.com. Также был использован файловый менеджер SA-filemanager http://www.softartisans.com.
Популярную компоненту CDO я не использовал из-за того, что она работает только с почтовыми серверами, основанными на IIS.
Прием почты
Для соединения с POP сервером был использован следующий код:
Set pop3 = Server.CreateObject( "JMail.POP3" )
pop3.Connect login, pass, pop_server
где login, pass - соответствующие параметры почтового сервера Unix, pop_server - переменная, содержащая адрес почтового сервера.
Чтение заголовков сообщений осуществляется следующим образом:
Response.Write("папка Inbox: "&
pop3.Count & " сообщений")
Response.Write " <br>размер ящика
" & pop3.Size & " байт "
i=1
if pop3.count <> 0 then
Response.Write "<hr>"
pop3.DownloadHeaders
pageCount=int(pop3.Count/pageSize)
if pageCount=0 then pageCount=0 else
if pageCount*pageSize<pop3.Count then
pageCount=pageCount+1
Response.Write "<div align='center'>"
for i=1 to pageCount
Response.Write "<a href='pop.asp?curpage="
& i-1 & "'>" _
& i & "</a> "
next
Response.Write "<br>"
Response.Write " страница " & curpage+1 & "
из " & pageCount
Response.Write "</div>"
%>
<form method="post">
<table border="1" cellspacing="1"
cellpadding="0"
bordercolor="DodgerBlue">
<tr bgcolor="DodgerBlue">
<td> </td>
<td> </td>
<td align="center">от кого</td>
<td align="center">получено</td>
<td align="center">тема</td>
</tr>
<%
for i=1 to pageSize
if curpage*pageSize+i>pop3.Count then exit for
%>
<tr>
<td><input type="checkbox" name="checkDel"
value="<%=curpage*pageSize+i%>"></td>
<td align="center"><%if inStr(1,
pop3.Messages.Item(curpage*pageSize+i).Charset,
"iso-8859-1",1)<>0 then
Response.Write "<img src='image/attachment.gif'
width='13' height='14'>"%>
</td>
<td>
<%Response.Write " " &
pop3.Messages.item(curpage*pageSize+i).From %>
</td>
<td><%
=pop3.Messages.item(curpage*pageSize+i).Date
%></td>
<td>
<a href="read_message.asp?
id=<%=curpage*pageSize+i%>">
<%
select case Request.QueryString("kode")
case "koi"
Response.Write(koiTowin1251
(pop3.Messages.item(curpage*pageSize+i).Subject))
case "win"
Response.Write(pop3.Messages.
item(curpage*pageSize+i).Subject)
case else
if inStr(1,pop3.Messages.Item
(curpage*pageSize+i).Charset,"koi8-r",1) <>0
or inStr(1,pop3.Messages.Item
(curpage*pageSize+i).Charset,
"iso-8859-1",1) <>0 then
Response.Write(koiTowin1251(
pop3.Messages.item
(curpage*pageSize+i).Subject))
else
Response.Write(pop3.Messages.item
(curpage*pageSize+i).Subject)
end if
end select
%>
</a>
</td>
</tr>
<%
next
%>
</table>
<input type="submit" value="удалить" name="delBut">
</form>
И в конце страницы
<%
pop3.Disconnect
set pop3=Nothing
%>
При получении писем пришлось решать следующие проблемы: перекодировка сообщений, пришедших в кодировке KOI8-R, удаление сообщений, постраничное отображение полученных заголовков писем.
Проблема перекодировки сообщений возникает в случае, если сообщение приходит в кодировке koi8-r. Так как страница разработана в кодировке windows-1251, то вывод текста ссобщения без перекодировки привидет к тому что на странице будет текст в двух кодировках, что неприемлимо. Для этого создана функция перекодировки из koi8-r в windows-1251
function koiTowin1251(strkoi)
dim winArray
dim koiArray
dim i
dim result
dim indexFind
winArray="абвгдежзийклмнопрстуфхцчш
щъыьэюяАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
koiArray = "БВЧЗДЕЦЪЙКЛМНОПРТУФХЖИ
ГЮЫЭЯЩШЬАСвчздецъйклмнопртуфхжигюыэящшьас"
for i=1 to len(strkoi)
indexFind=instr(1,koiArray,mid(strkoi,i,1))
if indexFind<>0 then
result=result+mid(winArray,indexFind,1)
else
if mid(strkoi,i,1)=chr(13) then
i=i+1
result=result+"<br>"
else
result=result+mid(strkoi,i,1)
end if
end if
next
koiTowin1251=result
end function
Выбор между кодировками осуществляется при помощи передачи странице кода выбранной кодировки.
Для удаления сообщений достаточно использовать метод DeleteSingleMessage(id) компонеты JMail. Для этого необходимо следующее:
- при первом просмотре заголовков запомнить номер сообщения в тэге input
<input type="checkbox" name="checkDel" value="<%=curpage*pageSize+i%>">
- при помощи кнопки submit передать это значение форме, содержащей серверный скрипт, удаляющий выбранное сообщение
Почтовое сообщение удаляется следующим скриптом:
if inStr(Request.ServerVariables("Request_Method"),
"POST")<>0 then
pop3.DownloadHeaders
for i=1 to Request.Form("checkDel").Count
pop3.DeleteSingleMessage(int(Request.
Form("checkDel")(i)))
next
pop3.Disconnect
set pop3=Nothing
Response.Redirect "pop.asp"
End if
В данном скрипте проверяется , каким методом странице переданы параметры, и после этого сообщение удаляется.
Постраничное отображение полученных заголовков писем необходимо, если в почтовом ящике находится большое количество писем. Поэтому необходимо обеспечить отображение заголовков писем наборами по 10 штук ( например), и предоставить выбор нужного набора. Для этого странице передается параметр curpage в url старницы. Затем номер страницы инициализируется с помощью следующего кода
if len(Request.QueryString("curpage"))=0 then
curpage = 0
else
curpage= CInt (Request.QueryString("curpage"))
end if
Затем, на основе полученного значения и отображается выбранная страница. Выбор номера нужного набора сообщений я предоставляю следующим образом
pageCount=int(pop3.Count/pageSize)
if pageCount<>0 then
if pageCount*pageSize<pop3.Count
then pageCount=pageCount+1
end if
Response.Write "<div align='center'>"
for i=1 to pageCount
Response.Write "<a href='pop.asp?curpage=" _
& i-1 & "'>" & i & "</a> "
next
Response.Write "<br>"
Response.Write " страница " &
curpage+1 & " из " & pageCount
Response.Write "</div>"
Чтение выбранного сообщения
При чтении сообщения возникает проблема кодировки, корректного отображения тела сообщения на asp странице, сохранения вложенных файлов на машину клиента.
Метод решения проблемы кодировки описан выше.
Проблема отображения заключается в следующем: в теле сообщения переход на новую строку указан комбинацией специальных символов "перевод каретки" и "переход строки", которые игнорируются броузером. Для этого надо заменить все вхождения данных симолов на тэг <br> то есть комбинацию chr(13)chr(10) на "<br>" для этого создана функция convertForHTML
function convertForHTML(str)
dim result
dim i
result=""
for i=1 to len(str)
if mid(str,i,1)=chr(13) then
i=i+1
result=result+"<br>"
else
result=result+mid(str,i,1)
end if
next
convertForHTML=result
end function
Для сохранения вложений на машину клиента я использовал примеры с сайта
http://www.aspfaqs.com/demos/StreamBinaryDemo.asp,
http://prosto.pp.ru/Menu/Menu.htm и файловый менеджер SA-FileManager. Пример сохранения вложений
<%@ Language=VBScript%>
<!-- #include file="include/general.asp"-->
<%
dim id
dim attach
dim oFM
dim oBS
dim id_att
dim item
dim sbody
dim mess
dim i
on error resume next
login=Request.Cookies("login")
pass=Request.Cookies("pass")
fio=Request.Cookies("fio")
if len(login)= 0 and len(pass)=0
then Response.Redirect("index.asp")
Set pop3 = Server.CreateObject("JMail.POP3")
pop3.Connect login, pass, smtp_server
id=Request.QueryString("id")
id_att=Request.QueryString("id_att")
pop3.DownloadMessages
Set oFM = CreateObject("SoftArtisans.FileManager")
set attach=pop3.Messages(id).
Attachments.Item(int(id_att))
if oFM.FileExists(Server.MapPath("temp") _
& "" & attach.Name)=true then
oFM.DeleteFile Server.MapPath("temp") _
& "" & attach.Name
attach.SaveToFile Server.MapPath("temp")
& "" & attach.Name
Set oBS = oFM.OpenBinaryFile(Server.MapPath
("temp") & "" & attach.Name)
Response.Addheader "Content-Disposition",
"attachment; filename=" & attach.Name
Response.ContentType=attach.ContentType
sbody=oBS.readAll
Response.BinaryWrite(sbody)
oBS.Close
oFM.DeleteFile Server.MapPath("temp")
& "" & attach.Name
set oBS=nothing
set attach=nothing
set sbody=nothing
set oFM=nothing
pop3.Disconnect
set pop3=Nothing
set mess=nothing
if Err.number<> 0 then
%>
<!-- #include file="error.asp"-->
<% end if
%>
Скрипт, осуществляющий чтение выбранного сообщения
<table bgcolor=Wheat align=center border="1"
cellspacing="0" cellpadding="0"
bordercolor=DodgerBlue width=90%>
<tr>
<td>тема</td>
<td>
<%
select case Request.QueryString("kode")
case "koi"
Response.Write(koiTowin1251(pop3.
Messages.item(id).Subject))
case "win"
Response.Write(pop3.Messages.
item(id).Subject)
case else
if inStr(1,pop3.Messages.Item(id).
Charset,"koi8-r",1) <>0
or inStr(1,pop3.Messages.Item(id).
Charset,"iso-8859-1",1)
<>0 then
Response.Write(koiTowin1251
(pop3.Messages.item(id).Subject))
else
Response.Write(pop3.Messages.
item(id).Subject)
end if
end select
%>
</td>
</tr>
<tr>
<td>автор</td>
<td>ответить на <a
href="send_message.asp?toAddress=
<%=pop3.Messages.Item(id).
From%>"><%
if len(pop3.Messages.item(id).
FromName) <> 0 then
if inStr(1,pop3.Messages.Item(id).
Charset,"koi8-r",1) <>0
or inStr(1,pop3.Messages.
Item(id).Charset,"iso-8859-1",1) <>0 then
Response.Write(koiTowin1251
(pop3.Messages.item(id).FromName))
else
select case Request.QueryString("kode")
case "koi"
Response.Write(koiTowin1251
(pop3.Messages.item(id).FromName))
case "win"
Response.Write(convertForHTML
(pop3.Messages.item(id).FromName))
case else
if inStr(1,pop3.Messages.Item(id).
Charset,"koi8-r",1) <>0
or inStr(1,pop3.Messages.Item(id).
Charset,"iso-8859-1",1) <>0 then
Response.Write(koiTowin1251
(pop3.Messages.item(id).FromName))
else
Response.Write(convertForHTML
(pop3.Messages.item(id).FromName))
end if
end select
end if
else
Response.Write " <" & pop3.
Messages.item(id).From & ">"
end if
%></a></td>
</tr>
<%
if pop3.Messages.Item(id).Attachments.
Count <> 0 then
%>
<tr>
<td>вложения</td>
<td><%
for i=0 to pop3.Messages.Item(id).
Attachments.Count-1
%>
<a href="save_client.asp?id=
<%=id%>&id_att=<%=i%>">
<%
Response.Write pop3.Messages(id).
Attachments.Item(i).Name _
& " " & pop3.Messages.Item(id).
Attachments.Item(i).Size _
& " байт</a><br>"
next
%>
<%'=" type " & pop3.Messages(id).
Attachments.Item(0).ContentType%>
</td>
</tr>
<%
end if
%>
<tr>
<td valign="top"> сообщение </td>
<td valign="top">
<%
select case Request.QueryString("kode")
case "koi"
Response.Write(koiTowin1251(pop3.
Messages.item(id).Body))
case "win"
Response.Write(convertForHTML(pop3.
Messages.item(id).Body))
case else
if inStr(1,pop3.Messages.Item(id).
Charset,"koi8-r",1) <>0
or inStr(1,pop3.Messages.Item(id).
Charset,"iso-8859-1",1) <>0 then
Response.Write(koiTowin1251(pop3.
Messages.item(id).Body))
else
Response.Write(convertForHTML(pop3.
Messages.item(id).Body))
end if
end select
%>
</td>
</tr>
</table>
Отправка сообщений
Для отправки сообщений использованы Mailer- и Upload- компонета с сайта http://www.dundas.com.
Пример отправки сообщения с вложенным файлом
if inStr(Request.ServerVariables
("Request_Method"),"POST")<>0 then
Dim objMailer 'Mailer control
Dim objUpload
set objUpload = Server.
CreateObject("Dundas.Upload.2")
set objMailer = Server.
CreateObject("Dundas.Mailer")
objUpload.UseUniqueNames=false
objUpload.UseVirtualDir=true
objUpload.MaxUploadSize=maxUploadSize
objUpload.Save "temp"
' послать
objMailer.SMTPRelayServers.Add smtp_server
' посылаем тело письма
if objUpload.Files.count = 0 then
objMailer.CustomHeaders.Add "Content-Type:",
"text/plain;charset=windows-1251"
objMailer.TOs.Add objUpload.Form("to")
objMailer.Subject = objUpload.Form("subject")
objMailer.Body = objUpload.Form("body")
objMailer.FromAddress = senderAddress
objMailer.FromName=senderName
else
' посылаем вложение
' Response.Write "<br>" & objUpload.
Files.count
if objUpload.Files.count <> 0 then
objMailer.TOs.Add objUpload.Form("to")
objMailer.Subject = objUpload.Form("subject")
objMailer.FromAddress = senderAddress
objMailer.FromName=senderName
For Each Item in objUpload.Files
objMailer.Attachments.Add Item.Path,
Item.OriginalPath,
Item.ContentType,"BASE64","windows-1251"
Next
objMailer.Body = objUpload.Form("body")
set item=nothing
end if
end if
objMailer.SendMail
Set objMailer = Nothing
set objUpload=nothing
send_ok=True
end if
Таким образом, достаточно простой web-интерфейс для почты на сайте готов. Данный сервис доступен по адресу
http://www.bashkirenergo.ru.