Что нового

[Сеть, интернет] Ошибка в формировании POST-запроса, (VK.API)

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Начал осваивать API вконтакта, все получается, но до сих пор не понимаю, почему фотография не загружается по POST запросу. Посмотрел примеры, которые рассматриваются на форуме - они у меня тоже не заработали. Затем я нашел в своем коде несколько логических ошибок, исправил их и в конечном итоге остановился на использовании WinHTTP-объекта. Свойства и параметры запроса составляю вручную.

Собстна, вот. Несколько вечеров я провел над подброкой параметров, изучением синтаксиса POST и тем, которые знать-то и не хотел никогда.
Код:
#include <inet.au3>
#include <HTTP_UDF.au3>

Dim $sServer, $sHash, $sPhoto, $sUploadServer, $sResponse, $sAnswer, $sRequest, $sPostData = ''
$sToken = "9176d92c656a28af1a63f6295f9806c16c8e37a1fdf05dcb6dc21a7fb68994f550e0db7e73f2285b7cdcd"
GetUploadServer($sUploadServer, $sToken)
;============= открываем файл
fOpen($sPostData, @ScriptDir & "\3.jpg", 16)
ExecPOST($sResponse, $sUploadServer, $sPostData)
_parseanswer($sResponse, $sServer, $sHash, $sPhoto)

If StringLen($sPhoto) > 2 Then
	ConsoleWrite('+UPLOAD DONE!' & @CRLF)
Else
	ConsoleWrite('+Upload error' & @CRLF)
	Exit
EndIf


Func GetUploadServer(ByRef $UploadServer, $Token)

	$request = "https://api.vk.com/method/photos.getUploadServer?&album_id=165659244&access_token=" & $Token
	$answer = _INetGetSource($request)
	$answer = StringReplace($answer, "\", "")
	$UploadServer = StringRegExpReplace($answer, ".*(http[^""]+)"".+", "$1")
	ConsoleWrite('UpServer = ' & $UploadServer & @CRLF)
EndFunc   ;==>GetUploadServer

Func ExecPOST(ByRef $Response, $UploadServer, ByRef $PostData)

	$oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1")
	$oHTTP.Open("POST", $UploadServer)
	$sBoundary =  @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & Random(0, 100000, 1) 
	$oHTTP.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" & $sBoundary )
	
	$sData = '--' & $sBoundary & @CRLF & _
			'Content-Disposition: form-data; name="file1"' & @CRLF & _
			'Content-Type: image/jpeg' & @CRLF & _
			'Content-Transfer-Encoding: binary' & @CRLF & @CRLF & _
			StringTrimLeft($PostData, 2) & @CRLF & _
			'--' & $sBoundary & '--' & @CRLF

	$oHTTP.SetRequestHeader("Content-Length", StringLen($sData))
	$oHTTP.Send($sData)
	$oHTTP.WaitForResponse
	$Response = $oHTTP.ResponseText
	ConsoleWrite('Response = ' & $Response & @CRLF)

EndFunc   ;==>ExecPOST


Func fOpen(ByRef $var, $path, $flag = 0)

	Local $hFile = FileOpen($path, $flag)
	$var = FileRead($hFile)
	FileClose($hFile)
	ConsoleWrite(StringLen($var) & ' bytes in file' & @CRLF)

EndFunc   ;==>fOpen


Ошибка в том, что поле photos_list, которое возвращается функцией _parseanswer не может быть пустым!!! :scratch: а должно содержать список всяих параметров, а мне приходят лишь пара квадратных скобок. Поэтому я пока удачу/неудачу загрузки фото проверяю по размеру поля фото в JSON. Удач пока не было. ваши предложения? Что не так? Куда смотреть? техподдержка VK молчит
 
Автор
C

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Я решил вопрос сам) компиляцией из аналогичных проблем на этом форуме. работает безотказно.
 

prostoix

Новичок
Сообщения
8
Репутация
0
А Я так и застрял :'( мне в ответ прилетает {"server":******,"photo":"[]","hash":"***********************"}
что значит что запрос ок а файл вы не приложили...
но видео нормально загружает....

:whistle: а можешь поделиться самой строкой POST запроса?
что у тебя после 'пустой строки вставляется по факту' :scratch:
 
Автор
C

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Код:
Func ExecPOST(ByRef $Response, $UploadServer, $hFilepath)
	Local $PostData = ''
	fOpen($PostData, $hFilepath)
	$oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1")
	$oHTTP.Open("POST", $UploadServer)
	$sBoundary = @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & Random(0, 100000, 1) 
	$oHTTP.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" & $sBoundary)
	$sData = '--' & $sBoundary & @CRLF & _
			'Content-Disposition: form-data; name="photo"; filename="egegersv.jpg"' & @CRLF & _
			'Content-Type: image/jpeg' & @CRLF & _
			'Content-Transfer-Encoding: binary' & @CRLF & @CRLF
	$bData = StringToBinary($sData)
	$bData &= $PostData
	$sData = @CRLF & '--' & $sBoundary & '--' & @CRLF
	$bData &= StringToBinary($sData)
	$oHTTP.Send($bData)
	$oHTTP.WaitForResponse
	$Response = $oHTTP.ResponseText
	ConsoleWrite('HTTP Response = ' & $Response & @CRLF)



Func fOpen(ByRef $var, $path)

	Local $hFile = FileOpen($path, 16)
	$var = FileRead($hFile)
	FileClose($hFile)
EndFunc   ;==>fOpen


EndFunc   ;==>ExecPOST



Вот, собстна!


Добавлено:
Сообщение автоматически объединено:

Функция возвращает в
Код:
byref $sResponse
ответ не с пустым 'photo', входящие параметры - адрес файлы и сервер приема фото.
 

prostoix

Новичок
Сообщения
8
Репутация
0
:IL_AutoIt_1: работает
:ok: спасибо

Малость поправил...

Код:
Func ExecPOST(ByRef $Response, $UploadServer, $hFilepath)
    Local $PostData = ''
    fOpen($PostData, $hFilepath)
    $oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1")
    $oHTTP.Open("POST", $UploadServer)
    $sBoundary = @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & Random(0, 100000, 1)
    $oHTTP.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" & $sBoundary)
    $sData = '--' & $sBoundary & @CRLF & _
            'Content-Disposition: form-data; name="photo"; filename="' & StringRegExpReplace($hFilepath, '^.*\\', '') & '"' & @CRLF & _
            'Content-Type: image/jpeg' & @CRLF & _
            'Content-Transfer-Encoding: binary' & @CRLF & @CRLF
    $bData = StringToBinary($sData)
    $bData &= $PostData
    $sData = @CRLF & '--' & $sBoundary & '--' & @CRLF
    $bData &= StringToBinary($sData)
    $oHTTP.Send($bData)
    $oHTTP.WaitForResponse
    $Response = $oHTTP.ResponseText
    ConsoleWrite('HTTP Response = ' & $Response & @CRLF)
EndFunc   ;==>ExecPOST

Func fOpen(ByRef $var, $path)
    Local $hFile = FileOpen($path, 16)
    $var = FileRead($hFile)
    FileClose($hFile)
EndFunc   ;==>fOpen
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
prostoix,
Предупреждение За нарушение правил форума (пункт В.11):
Любые отрывки AutoIt кода необходимо заключать в тег [autoit]
autoit.gif
(подробнее), а обычный код соответственно в тег [code]
code.gif
(подробнее). Также большие выдержки текста помещайте под тег [spoiler]
spoiler.gif
(подробнее), там где это поддерживается естественно. Как в случае с названием темы, также короткое и эргономичное сообщение привлекает больше внимания, и шансы на получение конкретного ответа увеличиваются.


С уважением, ваш Глобальный модератор.
 

prostoix

Новичок
Сообщения
8
Репутация
0
А ты не сталкивался при сохранении фото с проблемой :scratch: 121 - Invalid hash
 
Автор
C

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Неа, смори пробелы лишние! или другие символы, которые ты как-то выдирал.

Код:
Func _GetSaveVars($Response, ByRef $server, ByRef $hash, ByRef $photo)
	$server = StringRegExpReplace($Response, '.+server[^:]:+([^,]+),.+', '$1')
	$hash = StringRegExpReplace($Response, '.+"hash":"([^"]+)".*', '$1')
	$photo = StringReplace(StringRegExpReplace($Response, '.+"photo":"(\[\{.*\}\])[^\]]+$', '$1'), '\', '')
	ConsoleWrite('server = ' & $server & @CRLF)
	ConsoleWrite('hash = ' & $hash & @CRLF)
	ConsoleWrite('photo = ' & $photo & @CRLF)
EndFunc   ;==>_GetSaveVars


Func _SendSaveRequest($iGroup_id, $sServer, $sHash, $sPhoto, $sToken, ByRef $sPid, ByRef $ERRMSG)
	Sleep(300)
	Local $sRequest = 'https://api.vk.com/method/photos.saveWallPhoto?server=' & $sServer & _
			'&hash=' & $sHash & _
			'&photo=' & $sPhoto & _
			'&group_id=' & $iGroup_id & _
			'&access_token=' & $sToken
	Local $sResponse = ''
	_HTTPGET($sResponse, $sRequest)
	ConsoleWrite($sResponse & @CRLF)
	If StringInStr($sResponse, 'error_msg') Then
		$ERRMSG = 'While sending save request - ' & StringRegExpReplace($sResponse, '.+"error_msg"\:"([^"]+)".+', '$1')
		SetError(1)
	EndIf

	$sPid = StringRegExpReplace($sResponse, '.+"pid":(\d+),".*', '$1')
	ConsoleWrite('pid = ' & $sPid & @CRLF)
	$sPid = 'photo%ТВОЙ_ИД%' & '_' & $sPid
	;$sPid = 'photo-'  & $TargetGroup  & '_' & $sPid

EndFunc   ;==>_SendSaveRequest


Func _HTTPGET(ByRef $sResponse, $sURL)

	Local $oHTTP = ObjCreate('WinHttp.WinHttpRequest.5.1')
	$oHTTP.Open("GET", $sURL)
	$oHTTP.Send('')
	$oHTTP.WaitForResponse
	$sResponse = $oHTTP.ResponseText

EndFunc   ;==>_HTTPGET


В первой функции засовываешь Респонс от моей предыдущей функции - получаешь три значения в три переменные. Затем с ними делаешь сохранение второй функцийе - получаешь photo*****-***** в $Pid и сообщение об ошибке, если у Хьюстона проблемы :smile: убить ERRMSG захочешь - убивай, не критично.
 

prostoix

Новичок
Сообщения
8
Репутация
0
Огромное спасибо :beer:
Нашел благодаря твоему коду ошибку.
Усе работает. Спасибо еще раз, если бы не ты еще бы наверное неделю сидел подбородок зачесывал :scratch:.
 
Автор
C

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Я, кстати, сам неделю сидел! С F5 краска стерлась даже! Ответ нашел именно на просторах форума, что надо бинаризировать ваще все в передаваемой строке с данными! дальше фигня! Сейчас осваиваю VkScript.
 

ulan44

Знающий
Сообщения
55
Репутация
8
Камрады есть у кого HTTP_UDF.au3 выложите пожалуйста
 
Верх