MSXML2.ServerXMLHTTP and national characters - utf-8

This question is related to this one: Character encoding Microsoft.XmlHttp in Vbscript, but differs in one thing, the national characters are in the domain name, not only arguments.
The task is: download a page from the given URL.
I already solved problem of passing UTF8 string into VBScript by reading it from UTF8 encoded file through ADO.
But now when I try opening it MSXML2.ServerXMLHTTP returns error: The URL is invalid.
Here is VBScript code:
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile("fileWithURL.txt")
url = objStream.ReadText()
objStream.Close
Set XMLHttpReq = CreateObject("MSXML2.ServerXMLHTTP")
XMLHttpReq.Open "GET", url, False
XMLHttpReq.send
WEBPAGE = XMLHttpReq.responseText
If you put something like hxxp://россия.рф/main/page5.html into the UTF8 encoded fileWithURL.txt the script will raise an error while working ok with hxxp://google.com.
The workaround is to use ascii representation of the domain name - but I yet haven't found PunnyCode encoder for vbscript (apart from Chillkat which is an overkill for my task).
Will appreciate your help on the main problem or workaround.

I've made an amazing journey in to depth of my hard drive and found a code writen by / for Jesper Høy. This was the source code of SimpleDNS Plus' IDN Conversion Tool at that time.
Archive.org page snapshot: http://www.simpledns.com/idn-convert.asp
Archive.org file snapshot: idn-convert-asp.zip
You can also copy the whole code from this gist.
Create a function to convert URLs.
Function DummyPuny(ByVal url)
Dim rSegments : rSegments = Split(url, "/")
If UBound(rSegments) > 1 Then
rSegments(2) = DomainPunyEncode(rSegments(2))
End If
DummyPuny = Join(rSegments, "/")
End Function
Then convert your url before making the request.
XMLHttpReq.Open "GET", DummyPuny(url), False

Related

encoding problem for SUBJECT of email using CDO

Using vbscript (asp) with CDO I have problem with encoding in SUBJECT of email. I have used two solutions for BODY part of email and both works but non of them works for SUBJECT part.
First solution: Endcoding characters of email BODY using chrw (not working for subject):
for x=1567 to 1785
encoded="&#" & x & ";"
Body= Replace(Body, chrw(x), encoded, 1, -1, 1)
next
Second solution: setting HTMLBodyPart encoding:
objMessage.HTMLBodyPart.Charset = "utf-8"
is there something similar for SUBJECT part of email (e.g. objMessage.SubjectPart.Charset)?
Try:
objMessage.TextBodyPart.Charset = "utf-8"
or simply:
objMessage.BodyPart.Charset = "utf-8"
It has been documented elsewhere that modifying the Charset of the TextBodyPart also impacts (the plain/text) Subject.
Hope this helps.

VBS to save binary64 picture data as .jpeg file

I need to extract user pictures out of Active Directory (LDS) and save them as a .jpeg file. I am able to extract the binary 64 data for the photo attribute in AD but I don't know how to write it to a usable .jpeg file in my .vbs script. Please post sample code!
Since you already have the extracted binary data.. here's a sub to take that data and create a .jpg file. Just pass the binary data and a path to save (ie. c:\temp\pic.jpg).
Sub writeImage(binaryData, strFullPath)
Set objADO = CreateObject("ADODB.Stream")
objADO.Open
objADO.Type = 1
objADO.Position = 0
objADO.Write binaryData
objADO.SaveToFile strFullPath
Set objADO = Nothing
End Sub
If you didn't have the data, you could use this to pull it from a URL.
Function binaryURL(strURL)
Set objHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
objHTTP.Open "GET", strURL, False
objHTTP.Send
binaryURL = objHTTP.ResponseBody
End Function
And then just do a..
Call writeImage(binaryURL("http://i.imgur.com/fr16Y6W.jpg"), "C:\temp\pic.jpg")

Is XMLHTTP's responsebody working asynchronously in VB6?

We have a SSRS integrated sharepoint server. I am trying to get a report exported as PDF from it.
(I had to do like this, because my url is too long. I would rather use Shell command to do like this, although this looks like a better solution.)
Here'is my code:
Dim request as New XMLHTTP
Dim oStream as New Stream
Dim aBunchOfMiliseconds as Long
Dim fileLocation as String
Dim reportUrl as String
aBunchOfMiliseconds = 500
reportUrl = "http://www.mySharepointDomain.com/_vti_bin/ReportServer?http://www.mySharepointDomain.com/sites/AFolderHere/OOAnotherFolder/BlaBlaReportFolder/FolderFolder/AhTheLastOne/AtLeastMyReportFile.rdl&rs:Command=Render&rc:Toolbar=true&rs:Format=PDF&Parameter1=ABC &Parameter2=1&Parameter3=1&TheLastParameter=IllBeDamned&rs%3aParameterLanguage=ln-LN"
request.Open "GET", reportUrl
request.setRequestHeader "WWW-Authenticate", "NTLM" 'For impersonation
request.Send 'Go get it Bruce
If request.Status = 200 Then 'Are you successful?
oStream.Type = adTypeBinary
oStream.Open
oStream.Write request.responseBody 'Here's the problematic part
Sleep(aBunchOfMiliseconds) 'If I don't do this, file will be corrupted
oStream.SaveToFile fileLocation, adSaveCreateOverWrite
oStream.Close
End If
Set oStream = Nothing
Set request = Nothing
If I comment out the "Sleep" line, I will have a corrupted file that can not open. This code works fine but I found it ridiculus to use "Sleep" there.
Is there any way me to understand that the data copy operation is completed?
Oh I get it.
I've missed to say that "this is not an async call".
request.Open "GET", reportUrl, False

msxml3.dll Access Denied

I have the following code:
Function filejson(json)
Dim objStream, strData
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile(json)
strData = objStream.ReadText()
filejson = strData
End Function
Function http2json(url)
Set http = CreateObject("Microsoft.XmlHttp")
http.open "GET", url, FALSE
http.send "" '<------- Line 13
http2json=http.responseText
End Function
Function str2json(json,value)
Set scriptControl = CreateObject("MSScriptControl.ScriptControl")
scriptControl.Language = "JScript"
scriptControl.AddCode("x="& json & ";")
str2json= scriptControl.Eval( "x"& value )
End Function
Function get_json_from_file(json,value)
get_json_from_file=str2json(filejson(json),value)
End Function
Function get_json_from_http(url,value)
get_json_from_http=str2json(http2json(url),value)
End Function
Function save_json_from_http(url,loc)
Set fso = CreateObject("Scripting.FileSystemObject")
fullpath = fso.GetAbsolutePathName(loc)
Dim objStream, strData
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.WriteText http2json(url)
objStream.SaveToFile fullpath, 2
save_json_from_http=fullpath
End Function
Wscript.Echo save_json_from_http("http://api.themoviedb.org/3/authentication/session/new?api_key=#####some_api_key_example#####&request_token=#####some_default_request_token######&_ctime_json_=1372670635.164760555","tmdb\temp\_tmdb_sock_w.164519518.2109")
When I run this code, I get the following error.
If I remove &request_token=#####some_default_request_token###### it works just fine.
I also tried this: I added again the request_token, and I just typed a random character in it, for example, rexfuest_token, and strangely it worked. It seems there's a wrong parse in msxml3.dll. with request_token word.
Ideas?
This problem could be related to the security issues in Windows. The best way to fix it is to replace Microsoft.XmlHttp/MSXML2.XMLHTTP with MSXML2.ServerXMLHTTP.
I see the topic is almost 2 years old and most likely the topic starter has solved is issue. I have experienced the same issue couple hours ago and google provided me several links. There are some of them:
https://social.msdn.microsoft.com/Forums/en-US/1abda1ce-e23c-4d0e-bccd-a323aa7f2ea5/access-is-denied-while-using-microsoftxmlhttp-to-get-a-url-link-in-vbscript-help?forum=xmlandnetfx
https://support.webafrica.co.za/index.php?/Knowledgebase/Article/View/615/41/msxml3dll-error-80070005-access-is-denied---loading-xml-file
http://www.experts-exchange.com/Programming/Languages/Scripting/ASP/Q_27305017.html
Try with a more recent version:
Set http = CreateObject("Msxml2.XMLHttp.6.0")
It could also be an issue with your Internet security settings (see here). Open the Internet Options applet in the Control Panel, select the zone for the website (probably "Trusted sites") in the Security tab and click Custom level….
In the section Miscellaneous set Access data sources across domains to Enabled.
Also can change URL from http to https. Me helps
For me the solution was to add the URL in trusted sites.
Internet explorer browser > Tools > Internet options > Security > Trusted sites > Sites > Add the URL under "Add this website to the zone: " and click add and save.

VBScript and loadXML: Invalid at the top level of the document. How to fix it?

This is my fort post on stackoverflow. I have searched many similiar Q&A's on this site but my conditions seem a bit different. here is my vbscript code:
------------ code snippet ---------------
xmlurl = "songs.xml"
set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = False
xmlDoc.loadXML(xmlurl)
if xmlDoc.parseError.errorcode<>0 then
'error handling code
msgbox("error! " & xmlDoc.parseError.reason)
end if
------------ end code snippet ---------------
XML:
<?xml version="1.0" encoding="UTF-8"?>
<nowplaying-info-list>
<nowplaying-info mountName="CKOIFMAAC" timestamp="1339771946" type="track">
<property name="track_artist_name"><![CDATA[CKOI]]></property>
<property name="cue_title"><![CDATA[HITMIX]]></property>
</nowplaying-info>
<nowplaying-info mountName="CKOIFMAAC" timestamp="1339771364" type="track">
<property name="track_artist_name"><![CDATA[AMYLIE]]></property>
<property name="cue_title"><![CDATA[LES FILLES]]></property>
</nowplaying-info>
<nowplaying-info mountName="CKOIFMAAC" timestamp="1339771149" type="track">
<property name="track_artist_name"><![CDATA[MIA MARTINA]]></property>
<property name="cue_title"><![CDATA[TOI ET MOI]]></property>
</nowplaying-info>
</nowplaying-info-list>
I also tried removing the first line in case maybe UTF-8 was not compatible with windows (saw some posts about this), but I still got the same error. I also tried unix2dos and vice versa in case there were carriage return issues (hidden characters embedded in the xml). I just can't seem to figure out what's wrong. It's such a simole XML file. I could parse it in a few minutes using perl regex but I need to run this script on windows so using vbscript. I use the same technique to parse XML from other sources without any issues. I cannot modify the XML unfortunately, it is from an external source.
I have this exact same error on both my Windows Vista home edition and Windows Server 2008. I am running the vbscript from the command line for testing so far (ie not in ASP).
Thanks in advance,
Sam
xmlDoc.loadXML() can load an XML string. It cannot retrieve a URL.
Use an XMLHTTPRequest object if you need to make an HTTP request.
Function LoadXml(xmlurl)
Dim xmlhttp
Set xmlhttp = CreateObject("MSXML2.XMLHTTP")
xmlhttp.Open "GET", xmlurl, false
' switch to manual error handling
On Error Resume Next
xmlhttp.Send
If err.number <> 0 Then
WScript.Echo xmlhttp.parseError.Reason
Err.Clear
End If
' switch back to automatic error handling
On Error Goto 0
Set LoadXml = xmlhttp.ResponseXml
End Function
Use like
Set doc = LoadXml("http://your.url/here")
Three addition remarks:
(1) As .parseError.reason tends to be cryptic, it pays to include its .srcTxt
property (and the parameter to .loadXml):
Dim xmlurl : xmlurl = "song.xml"
Dim xmlDoc : Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = False
xmlDoc.loadXML xmlurl
If 0 <> xmlDoc.parseError.errorcode Then
WScript.Echo xmlDoc.parseError.reason, "Src:", xmlDoc.parseError.srcText
Else
WScript.Echo "surprise, surprise"
End if
output:
Invalid at the top level of the document.
Src: song.xml
Of course, writing a Function/Sub that takes all properties of .parseError
into account and using that always, would be even better.
(2) To load a file or URL, use .load:
Dim xmlDoc : Set xmlDoc = CreateObject("Microsoft.XMLDOM")
Dim xmlurl
For Each xmlurl In Array("song.xml", "http://gent/~eh/song.xml", "zilch")
xmlDoc.async = False
if xmlDoc.load(xmlurl) Then
With xmlDoc.documentElement.firstChild
WScript.Echo xmlurl _
, .tagName _
, .firstChild.tagName _
, .firstChild.text
End With
Else
WScript.Echo xmlurl, xmlDoc.parseError.reason, "Src:", xmlDoc.parseError.srcText
End if
Next
output:
song.xml nowplaying-info property CKOI-ÄÖÜ
http://gent/~eh/song.xml nowplaying-info property CKOI-ÄÖÜ
zilch The system cannot locate the object specified.
Src:
(3) Using the DOM avoids all encoding problems (that's why I put some
german umlauts into 'your' file - which even made it to the DOS-Box output)
and makes RegExps (even Perl's) a second best choice.

Resources