I am using UTF8 encoding for ASP pages. I want to implement a CSV download functionality for my website. Below is my response setup
With Response
.Buffer = true
.Expires = 0
.Clear
.Charset = "UTF-8"
.CodePage = 65001
.AddHeader "Content-Type", "text/html;charset=UTF-8"
.AddHeader "content-encoding", "UTF-8"
.AddHeader "content-disposition", "attachment; filename=""AgedDebtors.csv"""
End With
Encoding is set for response headers still i am getting encoded foreign characters in resulting CSV. Tried few things for this but was not able to get it right. Please let me know what i am missing here
Set stream = CreateObject("ADODB.Stream")
stream.Open
stream.Type = 2 'text
stream.Position = 0
stream.Charset = "utf-8"
stream.WriteText str
you may want to save the converted stream into a new file, so write this
stream.SaveToFile filename, 2
And to close the stream use
stream.Close
Related
My webhook is receiving POST request (aplication/JSON) from a 360Dialog (whatsapp) API with escaped Unicode characters like this: \u05db\u05e0\u05e1\u05d2\u05db\u05d9. It should be Hebrew letters.
I'm trying to decode that using JavaScript runat server but seems like it is not changing. I found a potential solution in this question's solution but it still saves the un-escaped Unicode into the database.
<script language="javascript" runat="server">
URL = {
decode : function(s){return decodeURIComponent(s.replace(/\+/g, " "))}
}
</script>
<%
rs("smstext")=URL.decode(body2)
%>
The POST request is coming from 360dialog (a Whatsapp API) and hitting my webhook.
the request sends an application/json POST with information of incoming Whatsapp messages.
It seems the POST itself already has the Hebrew in it as \u05e0\u05e1\u05d9\u05d5\u05df i guess i need to figure out how to set the charset for that?
also, this unanswered question seems like my same problem.
I am trying to convert a request.BinaryRead into utf-8.
the output in the database is this: \u05e0\u05e1\u05d9\u05d5\u05df instead of נסיון
I am probably misunderstanding something as the output is not what I expected.
my code is:
<%#LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!--#include virtual="/include/aspjson.asp" -->
<%
If Request.TotalBytes > 0 Then
Dim lngBytesCount
lngBytesCount = Request.TotalBytes
body = BytesToStr(Request.BinaryRead(lngBytesCount))
Set db = CreateObject("ADODB.Connection")
db.Open "DSN=xxx"
set rs = Server.CreateObject("ADODB.Recordset")
rs.open "SELECT * FROM log_sms", db, 3, 3
rs.addnew
rs("smstext")=body
rs.update
rs.close
End if
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "utf-8"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
%>
If I replace rs("smstext")=body with rs("smstext")="נסיון", the value in the database is saved correctly.
The approach is sound the problem is because the text is escaped in the JSON body you will need to unescape those characters before saving the content to a database.
Would recommend using this particular JSON Parser as it will automatically handle unescaping the characters for you.
Useful Links
Classic ASP Convert Latin Characters to Unicode Escape Strings *(Contains useful information about escaping, which can help with the unescaping aspect).
The solution (thanks to #user692942 comments):
I replaced the aspJSON library I was using with rcdmk/aspJSON. It takes care of decoding escaped characters already and simplified the process.
Since the POST request to my webhook page is in application/JSON a JSON library is required anyways.
to my little understanding, i must use BinaryRead to fetch the data from such a request. And thus have to convert from byte to str.
the working code is as follows:
<%#LANGUAGE="VBSCRIPT" CODEPAGE="65001" LCID="1037"%>
<!--#include virtual="/wa/aspjson.asp" -->
<%
If Request.TotalBytes > 0 Then
Dim lngBytesCount
lngBytesCount = Request.TotalBytes
jsonbyte = Request.BinaryRead(lngBytesCount)
jsonStr = BytesToStr(jsonbyte)
Set JSON = New JSONobject
Set jsn = JSON.Parse(jsonStr)
Set contact = jsn.value("contacts")(0)
set profile = contact.value("profile")
profname = profile.value("name")
wa_id = contact.value("wa_id")
Set message = jsn.value("messages")(0)
from = message.value("from")
id = message.value("id")
timestamp = message.value("timestamp")
mtype = message.value("type")
set text = message.value("text")
body = text.value("body")
End If
Set db = CreateObject("ADODB.Connection")
db.Open "DSN=xxx"
set rs = Server.CreateObject("ADODB.Recordset")
rs.open "SELECT * FROM log_sms", db, 3, 3
rs.addnew
rs("sent")=DateAdd("s", timestamp, DateSerial(1970,1,1))
rs("from")=from
rs("to")="whatsapp"
rs("smstext")=body
rs("result")="received"
rs("msgid")=id
rs("snr")="r"
rs("type")=mtype
rs.update
rs.close
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "utf-8"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
I have a script that is submitting a POST request of a form via AJAX.
When I look at the network tab, it is coming back in the format below, which I cannot read with a standard Request.Form in Classic ASP. I am seeing this server variable added to the page request as well due to the AJAX request: HTTP_X_REQUESTED_WITH = XMLHttpRequest
The form is set up as a simple POST: <form method="post" action="/contact-submit">
I cannot change the script performing the AJAX request to update the content type, etc.
This is the “Request payload” in the response on the network tab below. I have googled for days and cannot figure this out. How do you access this data? I even tried reading it with a file upload script I have via ASPUpload, but Upload.Form("contact_name") does not work either, it's blank as well.
I tried a simple PHP script (I do not know how PHP works, but this script came with script performing the POST as a demo), and calling print_r($_POST) the script passes all the correct info in an array back in the response on network tab. What the heck!!
Does anyone know how to get this data back in Classic ASP?
Thanks so much for the help in advance.
Dennis
-----------------------------254001430938683980861095915686
Content-Disposition: form-data; name="contact_name"
Test Name
-----------------------------254001430938683980861095915686
Content-Disposition: form-data; name="contact_email"
test#test.com
-----------------------------254001430938683980861095915686
Content-Disposition: form-data; name="contact_message"
my message
-----------------------------254001430938683980861095915686--
I worked on a solution to reading the data, this works below. Not sure it is the best / least expensive way to do this, but it works!
Thanks to everyone for the help / tips. If anyone has a better way to parse the response above, I'm all ears :)
<%
Function BytesToStr(bytes)
Dim Stream
Set Stream = Server.CreateObject("Adodb.Stream")
Stream.Type = 1 'adTypeBinary
Stream.Open
Stream.Write bytes
Stream.Position = 0
Stream.Type = 2 'adTypeText
Stream.Charset = "iso-8859-1"
BytesToStr = Stream.ReadText
Stream.Close
Set Stream = Nothing
End Function
If Request.TotalBytes > 0 Then
Dim lngBytesCount, post
lngBytesCount = Request.TotalBytes
post = BytesToStr(Request.BinaryRead(lngBytesCount))
End If
Response.ContentType = "text/plain"
sContentType = Replace(Request.ServerVariables("CONTENT_TYPE"),"multipart/form-data; boundary=---------------------------","")
arrPost = Split(post,"-----------------------------" & sContentType)
For i = 0 to UBound(arrPost)
sVal = Replace(arrPost(i),"Content-Disposition: form-data; name=","")
arrVal = Split(sVal,Chr(10),1)
For a = 0 to UBound(arrVal)
If Instr(1, arrVal(a), "contact_name") <> 0 Then
Response.Write GetValue(arrVal(a), "contact_name")
End If
If Instr(1, arrVal(a), "contact_message") <> 0 Then
Response.Write GetValue(arrVal(a), "contact_message")
End If
Next
Next
Function GetValue(f_FullString, f_FieldName)
fieldval = Replace(f_FullString, """" & f_FieldName & """","")
'response.Write "_" & fieldval & "_<Br>"
arrVal1 = Split(fieldval,Chr(10),1)
For b = 0 to UBound(arrVal1)
newval = arrVal1(b)
newval = Left(newval,Len(newval) - 2)
newval = Right(newval,Len(newval) - 6)
'For z = 1 to Len(newval)
' CurrChar = Mid(newval, z, 1)
' Response.Write Asc(CurrChar) & "<bR>"
'Next
Next
GetValue = newval
End Function
%>
UPDATE:
This is another solution if you have ASPUpload installed. I tried this last night, but forgot to add Upload.Save (which would have saved me 4hours of work --- UGGGGGHHHH).
'http://www.aspupload.com/manual_memory.html
Set Upload = Server.CreateObject("Persits.Upload")
Upload.Save
Name = Upload.Form("contact_name")
Response.Write Name
I have a script where I need to set some Japanese text to a variable. But since vbscript is not supporting japanese texts, it get converted to some garbled text like トコジャパンã‹ã‚‰ã®æ–°è¦æ³¨æ–‡. My actual japanese text is トコジャパンからの新規注文.
My script will look like below
dim emlObj
set emlObj = CreateObject("EMailObject")
emlObj.Subject = "Train - New Orders From Costco Japan | コストコジャパンからの新規注文"
emlObj.Body = "Some japanese body text"
emlObj.Send()
I do not have any other options like storing this text in file or db and process in some other scripts as of now. since this script will be used by our customers and they will set their expected email body text. We'll use them for sending it as a mail.
I've also tried ADODB.Steam but that works only when reading the text from file.
Can someone please suggest a way to set the japanese text in vbscript?.
Edit:
To put a clarity on what i really needed.
I want to hard-code a japanese text to a variable in VBScripts.
You can use this solution:
Dim objStream, body, subject
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.WriteText "Subject in Japanese"
objStream.SaveToFile "C:\Subject.txt", 2
objStream.Close
objStream.Open
objStream.WriteText "Body in Japanese"
objStream.SaveToFile "C:\body.txt", 2
objStream.Close
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile "C:\Body.txt"
body = objStream.ReadText()
objStream.Close
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile "C:\Subject.txt"
subject = objStream.ReadText()
objStream.Close
' Now body is stored in body variable and subject is in subject now do anything with them
IMPORTANT: Since you are not using ADODB.Stream to load your content, then be sure to save your actual VBScript file as UTF-16 LE encoding. Your script may optionally benefit from a Unicode byte-order-mark (BOM) header, as well -- depending upon how the VBScript engine and EmailObject respond.
Once the VBScript file is in the proper encoding, this script works fine for me:
With CreateObject("CDO.Message")
With .Configuration.Fields
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.somemailserver.net"
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 10
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
.Update
End With
.BodyPart.Charset = "utf-8"
.BodyPart.ContentTransferEncoding = "base64"
.TextBody = "コストコジャパンからの新規注文"
.TextBodyPart.Charset = "utf-8"
.HTMLBody = "<p>コストコジャパンからの新規注文</p>"
.HTMLBodyPart.Charset = "utf-8"
.From = "me#somemailserver.net"
.To = "you#somemailserver.net"
.Subject = "Train - New Orders From Costco Japan | コストコジャパンからの新規注文"
.Send()
End With
Note: I am using CDO.Message above, not EmailObject.
Hope this helps.
I'm trying to write a script in VBScript which should open Microsoft Word and write down some text.
The script works as expected as long as the text I'm writing is in English.
However, when the text is in Hebrew or in Chinese I only get Gibberish in MS Word.
I tried to save the script file as UTF-8, but I can no longer run it after this change.
I also tried to wrap it so it will be a wsf script and it didn't worked either.
Couldn't find any other suggestion on Google.
Here is the script (This time I'm trying to write the word "שלום" in Hebrew).
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set fso = CreateObject("Scripting.FileSystemObject")
Set objDoc = objWord.Documents.Add()
Set objSelection = objWord.Selection
objSelection.TypeText "שלום"
When I run this script, it opens MS word and write down "ùìåí" instead of "שלום".
You can save a script file with the following encoding:
ANSI. Only 256 chars can be used: 0..127 is standard ASCII, and upper part depends on locale you have chosen in system settings, or overridden by SetLocale().
Unicode (UCS-2 or UTF-16, Little Endian). It works if saved with BOM, or without BOM. There is 1 112 064 available chars. In my opinion it is the easiest way for you to get your script to work. But file size increased by 2 times.
UTF-8. Encodes any symbol in Unicode code space. Script can be ran only if saved without BOM.
UTF-8 as .wsf file with first tag <?XML version="1.0" encoding="UTF-8"?>
ANSI, but put all strings like WScript.Echo ChrW(1513) & ChrW(1500) & ChrW(1493) & ChrW(1501).
Notepad++ and Notepad2 are handy to clearly set the necessary encoding.
Regarding item 3. Generally, Windows Script Host is unable to run script file in UTF-8 encoding with BOM, and recognizes each byte of UTF-8-encoded file without BOM as ANSI-encoded char, while downloading the file into memory. I can suggest a work-around that allows to rectify incorrectly recognized chars being contained in variables, but you know, Unicode is a better way. Here is example:
s = "שלום"
WScript.Echo s ' wrong encoding
r = FixChars(s)
WScript.Echo r ' שלום
Function FixChars(s)
Dim r, p
r = ""
For p = 1 To Len(s)
r = r & ChrB(Asc(Mid(s, p, 1)))
Next
With CreateObject("ADODB.Stream")
.Type = 2
.Mode = 3
.Charset = "Unicode" ' HKLM\SOFTWARE\Classes\MIME\Database\Charset
.Open
.WriteText r
.Position = 0
.Charset = "UTF-8"
r = .ReadText
.Close
End With
Do While LeftB(r, 2) = ChrB(&HFD) & ChrB(&HFF)
r = MidB(r, 3)
Loop
FixChars = r
End Function
You shouldn't change locale via SetLocale() from script start till FixChars() completion, otherwise it will give an error.And the following code is an example for item 4:
<?XML version="1.0" encoding="UTF-8"?>
<job>
<script language="VBScript">
<![CDATA[
WScript.Echo "שלום"
]]>
</script>
</job>
I would like to find the price with 2 year contract and display it in a message box. Sofar I have:
Dim MyPage
Dim Price
Set MyPage=CreateObject("Microsoft.XMLDOM")
MyPage.load("http://www.verizonwireless.com/b2c/store/controller?item=phoneFirst&action=viewPhoneDetail&selectedPhoneId=5723")
Wscript.Sleep 2000
Set Price = MyPage.getElementsByTagName("span")
For Each Elem In Price
MsgBox(Elem.firstChild.nodeValue)
Next
I understand that I am completely wrong, but I don't even know where to start. I love writing simple programs like this, but I just need help getting started. Any ideas will help!
Here a better version, uses the HTMLFile object
Dim HTMLDoc, XML, URL, table
Set HTMLDoc = CreateObject("HTMLFile")
Set XML = CreateObject("MSXML2.XMLHTTP")
URL = "http://www.verizonwireless.com/b2c/store/controller?item=phoneFirst&action=viewPhoneDetail&selectedPhoneId=5723"
With XML
.Open "GET", URL, False
.Send
HTMLDoc.Write .responseText
End With
Set spans = HTMLDoc.getElementsByTagName("span")
for each span in spans
WScript.Echo span.innerHTML
next
'=><SPAN>Set Location</SPAN>
'=>Set Location
'=><SPAN>Submit</SPAN>
'=>Submit
'=>Connect with us
the control you use is for reading XML documents, you need something like this
'Create an xmlhttp object, the string depends on the version that is installed
'on your pc could eg also be "Msxml2.ServerXMLHTTP.5.0"
Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
xmlhttp.Open "GET", "http://admin:pasword#10.0.0.2/doc/ppp.htm", False
xmlhttp.Send
text=xmlhttp.responseText
wscript.echo text
Set xmlhttp = Nothing
Run a search in your registry for XMLHTTP to get the right string/version for the identifier.
To get the tag from the html you can use the following
text = "blabla <span>this is what i need</span> bla bla<span>second item</span> end"
function getElementsByTagName(sTextToSeachIn, tag)
answer = ""
separator = ""
set oRegExpre = new RegExp
with oRegExpre
.IgnoreCase = true
.Global = true
.MultiLine = True
.Pattern = "<" & tag & ">(.*?)</" & tag & ">"
end with
set oColMatches = oRegExpre.Execute(sTextToSeachIn)
for each match in oColMatches
answer = answer & separator & match.subMatches(0)
separator = "|" 'use something that's not in the spancontents
next
if separator <> "" then
getElementsByTagName = split(answer, separator)
else
getElementsByTagName = array()
end if
end function
for each tag in getElementsByTagName(text, "span")
wscript.echo tag
next
'=>this is what i need
'=>second item
There are better techniques and certainly better languages than vbscript to do this, i suggest to take a look at Ruby which exels in such things.
Alex, in response to your comment about getting a cookie and running a javascript in HTMLFile, here a ruby script i found, hopes it helps you at some point, it reads in a page, passes it to the HTLMFile object and in that DOM executes a remote javascript file. It also gives you an idea of the combined power of activeX and Ruby.
require "win32ole"
$jsxpath_uri = "http://svn.coderepos.org/share/lang/javascript/javascript-xpath/trunk/release/javascript-xpath-latest-cmp.js"
uri, xpath = "http://gist.github.com/gists", "//div[#class='info']/span/a"
http = WIN32OLE.new('MSXML2.XMLHTTP')
http.Open "GET", uri, false
http.Send
text = http.responseText
dom = WIN32OLE.new("htmlfile")
dom.Write(text)
dom.parentWindow.eval(open($jsxpath_uri){|f| f.read })
items = dom.evaluate(xpath, dom, nil, 7, nil)
len = items.snapshotLength
(0...len).each do |i|
item = items.snapshotItem(i)
puts item.innerHTML
end