Rus Кодировка Query_string В Ls Documentcontext

NetWood

Well-Known Member
Lotus team
17.04.2008
371
16
#1
Кодировка на форме в UTF-8. Из нее, методом post, передаются на сервер данные, вот так:
Код:
	$("#username").blur(function()
{
$("#msgbox").removeClass().addClass('messagebox').text('Проверка...').fadeIn("slow");
$.post("doAjaxUsername?openagent&user_name="+$(this).val(),
function(data)
{
var result = $(data).siblings('#userreg').text();
var result2 = $(data).siblings('#Query_String').text();
alert(result+'	'+result2); // тестовое
if(result =='no') 
... // тут показываем страшные надписи - ДА-НЕТ
Внутри агента содержимое распарсивается вот так:
Код:
...
Set db = s.CurrentDatabase	
Set ctx= s.DocumentContext

encode = Strright(ctx.Query_String(0), "user_name=")	
'' если из формы передаются RUS буквы, то поиск не работает
''username = Evaluate(| @URLDecode("Platform";encode) |) '' не работает
''username = Evaluate ( { @URLDecode("Platform"; encode) }, ctx) '' тоже не пашет
username = encode

Set viewreg=db.GetView("Users")	
Set docpeople = viewreg.GetDocumentByKey(username,True)
'' проверить на наличие соответствий имен
If Not (docpeople Is Nothing) Then 
argtext="no"
Else
argtext="yes"
End If		

'' вывод данных для работы с AJAX JQUERY
Print ({<div id="userreg" style="display:none">} & argtext & {</div>} )
Print ({<div id="Query_String" style="display:none">} & username & {</div>})
...
Все работает, пока в поле #username не появляются русские буквы. В агенте они превращаются в кракозябы типа так Вася=%D0%92%D0%B0%D1%81%D1%8F и поиск GetDocumentByKey(username,True), соответственно, не пашет и все ломается :)

Вопросы:
1. Как внутри агента на LS поправить русскую кодировку на Query_String передаваемую из AJAX?
2. Другой подход.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#3
я упоминал про "другой" метод получения запроса...
ctx.Query_String_Decoded(0) (в моем коде через GetItemValue)
эссесвено до того его надо заенкодить :) - на JS это тоже было
 

NetWood

Well-Known Member
Lotus team
17.04.2008
371
16
#4
я упоминал про "другой" метод получения запроса...
ctx.Query_String_Decoded(0) (в моем коде через GetItemValue)
эссесвено до того его надо заенкодить :) - на JS это тоже было
Камрадос! Благодарю за ответы.
- decodeURI не успел заюзать. Буквари говорят нет смысла - jQuery всегда его в UTF-8 передает.
- С Query_String_Decoded жизнь не мила, там тоже грабли http://codeby.net/index.php?showtopic=23149

Полечил собственную кривизну рук и процесс ожил. У меня ошибка была в синтаксисе Evaluate. Итого полный код в агенте:
Код:
	...
Set ctx= s.DocumentContext	

url = ctx.Query_String(0)
encode = Strright( url , "user_name=")	
''Ахтунг! "Platform" не работает в Фоксе и работает в IE. Ставим только @URLDecode Domino
decode = Evaluate ({@URLDecode("Domino";"}+ encode +{")})	
username = decode(0) '' именно с ноликом
Set viewreg=db.GetView("Users")	
Set docpeople = viewreg.GetDocumentByKey(username,True)
If Not (docpeople Is Nothing) Then 
argtext="no"
Else
argtext="yes"
End If		

'' вывод данных для работы с AJAX JQUERY
Print ({<div id="userreg" style="display:none">} & argtext & {</div>} & argtext )
Print ({<div id="username" style="display:none">} & username & {</div>} & username )
...
Полный код на форме
Код:
$().ready(function()
{				 
$("#username").blur(function()	
{
$("#msgbox").removeClass().addClass('messagebox').text('Проверка...').fadeIn("slow");
$.post("doAjaxUsername?openagent&user_name="+$(this).val(),
function(data)
{
//нам JSON не указ. Разбираем по костям html
var result = $(data).siblings('#userreg').text();
var result3 = $(data).siblings('#username').text();
if(result =='no') 
{
$("#msgbox").fadeTo(200,0.1,function() 
{ 
$(this).html('Имя '+ result3 + ' уже занято').addClass('messageboxerror').fadeTo(900,1);
});		
}
else
{
$("#msgbox").fadeTo(200,0.1,function() 
{ 
$(this).html( result3 +' Это имя доступно для регистрации').addClass('messageboxok').fadeTo(900,1);	
});
}

});

});
});
Ссылка на пример для PHP http://ruseller.com/lessons/les174/example/index.html В этом примере сервер возвращает текстовый файл с одним параметром, а наш агент Domino возвращает всегда html. Мой код слегка допилен использованием .siblings для рапарсивания ответа агента.
Итого получаем простое решение контроля нового юзера с русскими буквами на web форме Domino через AJAX.
Тестировалось на Фоксе, IE, Яндексе=Хроме. Оперы у меня нет.
Такие пироги :)
 

Kizarek86

Well-Known Member
Lotus team
20.07.2007
863
6
#5
Я юзаю так:
перед принтом агента пришем

Print |Content-type:text;charset=UTF-8|

Для получение параметров юзаю класс:

Код:
Public Class RequestAjaxParser
Private sREQUEST As String

Sub New(DOC As NotesDocument)
Select Case DOC.Request_Method(0)
Case "POST":		sREQUEST = DOC.Request_Content(0)
Case "GET":		sREQUEST = DOC.Query_String_Decoded(0)
End Select
End Sub

Public Function GetFieldValues(sFieldName As String) As String
Dim FIELD_VALUES As String
FIELD_VALUES = Strright(sREQUEST,sFieldName + "=")
If Instr(FIELD_VALUES,"=") Then FIELD_VALUES = Strleft(FIELD_VALUES,"&")
FIELD_VALUES = Replace(Replace(FIELD_VALUES,{\},{\\}),{"},{\"})
If Len(FIELD_VALUES)<500 Then
GetFieldValues = Join(Evaluate({@URLDecode("UTF-8";"}+FIELD_VALUES+{")}))
Else
Dim ARR_FIELD_VALUES As Variant
ARR_FIELD_VALUES = Split(FIELD_VALUES,":")
Forall VALUES In ARR_FIELD_VALUES
VALUES = Join(Evaluate({@URLDecode("UTF-8";"} + VALUES + {")}))
End Forall
GetFieldValues = Join(ARR_FIELD_VALUES,":")
End If
End Function

End Class
Работает так:
Код:
	Dim RAP As RequestAjaxParser
Dim uPARAM1 As String, uPARAM2 As String
Set RAP = New RequestAjaxParser(s.DocumentContext)
uPARAM1 = RAP.GetFieldValues("PARAM1")
uPARAM2 = RAP.GetFieldValues("PARAM2")
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#6
NetWood
С Query_String_Decoded жизнь не мила, там тоже грабли http://codeby.net/index.php?showtopic=23149
в тесте, кот. обсуждали - все нормально передавалось
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"я тестил"</div></div><div class="sp-body"><div class="sp-content">
JavaScript:
function checkName(obj){
checkErrors='';
checkUser='';
var url=webdb +"WebSearchUser?OpenAgent&" + obj.name + "=" + obj.value;
printinfo(url);
var request=new Ajax.Request(url, {
method: 'get',
onSuccess: function(transport) {
var notice = $('advice-'+ obj.name);
var errordiv= $('error-'+ obj.name);
printinfo('start parsing...');
var txt='('+transport.responseText+')';
printinfo("wrapped text>\n" +txt + "\n");
var result = eval(txt);
if (!notice){
//			printinfo("check result for:" + obj.name + "; =" + result[obj.name]);
if (!isEmpty(result[obj.name])){
printinfo('add value:' + result[obj.name]);
checkNames.add(obj.name,result[obj.name]);
lastField=obj.name;
try{
updatestatus(result, errordiv);
errordiv.show();
//					errordiv.update('такое значение уже существует');
}catch(err){printinfo("err:" + err.message);}
}else{
try{
//					errordiv.update('');
errordiv.hide();
}catch(err){}
checkNames.remove(obj.name);
}
}
if (result.errors[0]!='end'){checkErrors.add(obj.name,result.errors);return 'error'}
//		return result.username;
}
});
}
классы
Код:
'encode возвращает вместо " " -> "+"
'http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URLEncoder.html
Class HttpBase As ErrorHandlerWJ
Private curdoc As NotesDocument
Private ses As NotesSession
Private isPrintedHeader As Boolean
Private isPrintedEnd As Boolean
Private decoderClass As JavaClass
Private encoderClass As JavaClass
Private encoderObj As JavaObject
Private Contenttype As String
Private msgList List As String
Private msgCount As Long
Private errList List As String
Private errCount As Long
Sub New()
Set ses=New NotesSession
Set curdoc=ses.DocumentContext
Set encoderClass=jSession.Getclass({java/net/URLEncoder})
Set decoderClass=jSession.Getclass({java/net/URLDecoder})
Contenttype={text}
End Sub

Sub Delete
Me.Close
End Sub

Property Get CGIvar(xName As String) As String
CGIvar=curdoc.GetItemValue(xName)(0)
End Property

Private Property Set Content As String

End Property

Property Get GetRequestParams As Variant
On Error Goto ErrH
Dim s As String
s=Fulltrim(GetRequestQuery)
If Len(s)>0 Then
GetRequestParams=Split(s,{&})
Else
s=Fulltrim(GetRequestPost)
If Len(s)>0 Then GetRequestParams=Split(s,{&})
End If
Quit:
Exit Property
ErrH:
Me.PrintError(Me.RaiseError)
Resume Quit
End Property

Property Get GetRequestQuery As String
On Error Goto ErrH
'используется Query_String_Decoded - не чувствует разницы между "+" и " "
'это поведение типично и потому "+" -> " "
GetRequestQuery=curdoc.getItemValue("Query_String_Decoded")(0)
Quit:
Exit Property
ErrH:
Me.PrintError(Me.RaiseError)
Resume Quit
End Property

Property Get GetRequestPost As String
On Error Goto ErrH
GetRequestPost=curdoc.getItemValue("Request_Content")(0)
Quit:
Exit Property
ErrH:
Me.PrintError(Me.RaiseError)
Resume Quit
End Property

Property Get GetRequesPath As String
GetRequesPath=curdoc.getItemValueString("Path_Info_Decoded")
End Property

Sub PrintMsg(msg As String)
PrintHeader
msgList({message_} &Cstr(msgCount))=msg
msgCount=msgCount+1
End Sub

Function Decode(msg As String) As String
Decode=decoderClass.decode(msg)
End Function

Function DecodeUTF8(msg As String) As String
DecodeUTF8=decoderClass.decode(msg,{UTF-8})
End Function

Function DecodeCP1251(msg As String) As String
DecodeCP1251=decoderClass.decode(msg, {Cp1251})
End Function

Function DecodeAll(msg As String, enc As String) As String
DecodeAll=decoderClass.decode(msg, enc)
End Function

Function EncodeAll(msg As String, enc As String) As String
EncodeAll=encoderClass.encode(msg, enc)
End Function

Function Encode(msg As String) As String
Encode=encoderClass.encode(msg)
End Function

Sub PrintMsgEncoded(msg As String)
PrintHeader
msgList({messageEnc_} &Cstr(msgCount))=encoderClass.encode(msg)
End Sub

Private Function PrintHeader As Boolean
On Error Goto ErrH
If isPrintedHeader Then Exit Function
'возвращаем результат в UTF-8
Print {Content-Type: } &Contenttype &{; charset=UTF-8"} 'text/xml;application/xml;
'		Print {Content-Type: } &Contenttype &{; charset=Windows-1251"}
isPrintedHeader=True
Me.PrintHeader=True
Quit:
Exit Function
ErrH:
Error Err, RaiseError
End Function

Private Function PrintEnd As Boolean
If Not isPrintedHeader Then Exit Function
If isPrintedEnd Then Exit Function
isPrintedEnd=True
Me.PrintEnd=True
End Function

Private Sub PrintError(msg As String)
PrintHeader
errList({error_} &Cstr(errCount))=msg
errCount=errCount+1
End Sub

Sub Close
PrintEnd
End Sub
End Class

Class HttpBaseXML As HttpBase
Function PrintHeader As Boolean
Dim b As Boolean
b=HttpBase..PrintHeader
Me.PrintHeader=b
If Not b Then Exit Function
Print {<?xml version="1.0" encoding="UTF-8"?>}
Print {<response>}
End Function

Sub New()
Contenttype={text/xml}
End Sub

Sub PrintMsg(msg As String)
PrintHeader
Print {<message>} &msg &{</message>}
End Sub

Sub PrintMsgEncoded(msg As String)
PrintHeader
Print {<messageenc>} &encoderClass.encode(msg) &{</messageenc>}
End Sub

Function PrintEnd As Boolean
Dim b As Boolean
b=HttpBase..PrintEnd
Me.PrintEnd=b
If Not b Then Exit Function
Print {</response>}
End Function

Sub PrintError(msg As String)
Call HttpBase..PrintError(msg)
Print {<error><object>} & Typename(Me) &{</object><message>} &msg &{</message></error>}
End Sub
End Class

Class HttpBaseJSON As HttpBase
Function PrintHeader As Boolean
Dim b As Boolean
b=HttpBase..PrintHeader
Me.PrintHeader=b
If Not b Then Exit Function
'		Print |{"response":[|
Print |{|
End Function

Sub New
Contenttype="application/json"
End Sub

Function PrintEnd As Boolean
Dim b As Boolean
b=HttpBase..PrintEnd
Me.PrintEnd=b
If Not b Then Exit Function
'		Print |"end":"end"]}|
Print |"end":"end"}|'заглушка, чтобы не заморачиваться на оконечные запятые
End Function

'	Sub PrintMsg(msg As String)
'		PrintHeader
'		Print {"message":"} &msg &{",}
'	End Sub

'	Sub PrintMsgEncoded(msg As String)
'		PrintHeader
'		Print {"message_enc":"} &encoderClass.encode(msg) &{",}
'	End Sub

Sub PrintJSONvar(xName As String, xValue As String)
PrintHeader
Print {"} &xName &{":"} &xValue &{",}
End Sub

'	Sub PrintError(msg As String)
'		Call HttpBase..PrintError(msg)
'		Print |"error":{"object":"| & Typename(Me) &|", "message":"| &msg &|"},|
'	End Sub

Sub Close
'разделим потоки ошибок и сообщений
'выводим ошибки из буфера
Print |errors:[|
Forall e In errList
Print |{"| & Listtag(e) & |":{"object":"| & Typename(Me) &|", "message":"| & e &|"}},|
End Forall
'если первым елементом - errors[0]=="end" - нет ошибок
Print |"end"],| 'зглушка окончания списка ошибок
'выаодим сообщения из буфера
Print |messages:[|
Forall m In msgList
'			Print |{"| &Listtag(m) &|":"| &m &|"},|
Print |"| &m &|",|
End Forall
'если первым елементом - messages[0]=="end" - нет сообщений
Print |"end"],| 'заглушка окончания списка сообщений
HttpBase..Close
End Sub
End Class

Class HttpObj As HttpBaseJSON
End Class
кусок агента
Код:
	Dim httpObj As New HttpObj()
Dim viewreg As NotesView

Set ses =New NotesSession
IsOnserver=ses.IsOnServer
Set db=ses.CurrentDatabase

Set viewreg=db.GetView(REG_VIEW)
viewreg.AutoUpdate=False
Dim fld As String, v, arrCheck
arrCheck=Split(CHECK_FLDS, LIST_SEP)
'используется Query_String_Decoded - не чувствует разницы между "+" и " "
v=httpObj.GetRequestParams
httpObj.PrintMsgEncoded({Query_String:} & httpObj.GetRequestQuery)
If Not Isempty(v) Then
Forall m In v
Dim lstr As String, s As String
s=Cstr(m)
lstr=Strleft(Cstr(s),{=})
'			If Cstr(m) Like {username=*} Then
If Not Isnull(Arraygetindex(arrCheck, lstr, 5)) Then
fld=Strright(s,lstr &{=})
'не кодируем часть сообщения (символы будут закодированы, а это не нужно)
httpObj.PrintMsg(lstr &{:} & httpObj.Encode(fld))
'даже если в имени будет "+" - в консоль будет записан " " (особенность Query_String_Decoded)
Msgbox "field value:" &fld
 

NetWood

Well-Known Member
Lotus team
17.04.2008
371
16
#7
to lmike
в тесте, кот. обсуждали - все нормально передавалось
Не осилил. Вроде все норм., но за гранью моего понимания. Сорри :)


Код:
Sub New(DOC As NotesDocument)
Select Case DOC.Request_Method(0)
Case "POST":		sREQUEST = DOC.Request_Content(0)
Case "GET":		sREQUEST = DOC.Query_String_Decoded(0)
End Select
End Sub
Методом $.post( у меня не взлетело. Переделал запрос на $.get( - ожило, но, например, если в запросе &name=Петя+Вася, то uPARAM1 = RAP.GetFieldValues("name") будет "Петя Вася" без плюса. Вместо плюса — пробел.

Переделал
Case "POST": sREQUEST = DOC.Request_Content(0)
на
Case "POST": sREQUEST = DOC.Query_String(0)
И методом $.post( все заработало как надо.

Плюсую вощем. Сэнкс :)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 492
367
#8
Методом $.post( у меня не взлетело. Переделал запрос на $.get( - ожило, но, например, если в запросе &name=Петя+Вася, то uPARAM1 = RAP.GetFieldValues("name") будет "Петя Вася" без плюса. Вместо плюса — пробел.
это и есть урлдекоде (см. каменты кода выше)