Имя: Пароль:
1C
1C 7.7
v7: Загрузка файла на Yandex.Disk с помощью XMLHttpRequest
0 Damash
 
28.03.22
09:29
Требуется реализовать функционал загрузки файлов на Yandex.Disk
https://yandex.ru/dev/disk/api/reference/upload.html

в ступор стал именно в момент уже конкретно отправки
каким образом присоединяется сам файл при отправке методом PUT?

Процедура глЗагрузитьОбновитьФайлНаЯндексДиске(token, УрлКYandexDisk, overwrite, ПутьКФайлуДляЗагрузки) Экспорт     
    httpobj=CreateObject("winhttp.winhttprequest.5.1");
    httpobj.Open("GET",УрлКYandexDisk,0);
    httpobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    httpobj.setRequestHeader("Authorization","OAuth " + token);
    httpobj.Send("");
    Сообщить("1: "+УрлКYandexDisk); // папка на Я.Диске, куда требуется закачка
    Сообщить("2: "+httpobj.status+":"+httpobj.statusText);
    
    Текст=0;
    Текст=СоздатьОбъект("Текст");
    Текст=httpobj.ResponseText;
    Текст=СтрЗаменить(Текст,"{""href"":""h","h");
    ТехУрл=СтрЗаменить(Текст,"""}","");
    Сообщить("3: "+ТехУрл); //технический url для закачки на Я.Диск

    ФС.УстТекКаталог("d:\");
    НашФайл=ФС.НайтиПервыйФайл("sale.jpg");
    
    **как присоединить к отправке?
    
    httpobj.Open("PUT",ТехУрл,0);    
    httpobj.Send();
    Сообщить("4: "+httpobj.status+":"+httpobj.statusText);
    Сообщить("5: "+httpobj.ResponseText); //ответ о результате закачки    
    httpobj=0;
КонецПроцедуры
1 MWWRuza
 
гуру
28.03.22
10:02
Эээ... Я наверное что-то не понимаю... А можно пояснить, зачем такие сложности? Зачем вообще API в данном случае?
В ЯндексДиске Можно подключить его папку как локальный ресурс и просто копировать/заменять/удалять на нем файлы...
У меня так обмен удаленных магазинов фронт <=> бэк сделан и работает, относительно стабильно, и уже давно.
Вот, три магазина(их папки обмека) как с центрального компьютера выглядят: https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/i-432.jpg
2 Damash
 
28.03.22
11:36
1C на удаленном сервере крутится, как такового файлового обмена и работы с файлами там нет.
Решил, что API будет быстрее, глядя на описание от Яндекс.
А так получается нужно на сервер залить прогу от Яндекса и дополнительно автообмен настроить.
3 acht
 
28.03.22
12:14
(0) на vbs это примерно так:

Const adTypeBinary = 1

Set request = CreateObject("WinHttp.WinHttpRequest")
Set dataStream = CreateObject("ADODB.Stream")

dataStream.Type = adTypeBinary
dataStream.Open
dataStream.LoadFromFile "C:\path\to\your.file"

request.Open "PUT", "http://your/url"
request.SetRequestHeader "Content-Type", "application/octet-stream"
request.Send dataStream
4 vladmenleo
 
28.03.22
12:21
(Функция глЗагрузитьНаВебДав(ФайлИсточник, ИмяКаталога, ИмяФайла) Экспорт
    x = СоздатьОбъект("Microsoft.XMLHTTP");
    x.Open("PUT","http://User:password@addresWebDav/" + ИмяКаталога + ИмяФайла,0); // третий параметр: 0-синхронный запрос, 1 - асинхронный PUT
    x.setRequestHeader("Accept", "*/*");
    x.setRequestHeader("Content-Type","application/binary");
    Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
    Скрипт.language = "vbscript";
    
    Stream = СоздатьОбъект("ADODB.Stream");
    Stream.Mode = 3;
    Stream.Type = 1;
    Stream.Open();
    Stream.LoadFromFile(ФайлИсточник);
    
    Скрипт.AddObject("s", Stream);
    Скрипт.AddObject("x", x);
    Скрипт.Eval("x.Send(s.Read())");
    Stream.Close();
    Возврат x.Status;
КонецФункции // ЗагрузитьНаВебДав)
Допили под себя имя пользователя, пароль имя ресурса подставь свои
5 acht
 
28.03.22
12:23
(4) > Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
Это зачем?
6 vladmenleo
 
28.03.22
12:26
(5) вот для этого
Скрипт.AddObject("s", Stream);

    Скрипт.AddObject("x", x);

    Скрипт.Eval("x.Send(s.Read())");

    Stream.Close();
7 acht
 
28.03.22
12:35
(6) А без него?

dataStream = СоздатьОбъект("ADODB.Stream")
dataStream.Type = 1;
dataStream.Open();
dataStream.LoadFromFile(ФайлИсточник);

request = СоздатьОбъект("WinHttp.WinHttpRequest")
request.Open("PUT", "http://your/url");
request.SetRequestHeader("Content-Type", "application/octet-stream")
request.Send(dataStream);
8 vladmenleo
 
28.03.22
12:45
(7) даже и не знаю. x.Send(Stream.Read()) без MSScriptControl.ScriptControl у меня не взлетело. я привел свою реально работающую сейчас функцию. Дальше что хочешь делай
9 acht
 
28.03.22
12:50
(8) Ох уж эти суровые семерочники, не желающие ни в чем разбираться...
10 timurhv
 
28.03.22
13:03
(2)
>Решил, что API будет быстрее, глядя на описание от Яндекс.

Порежут скорость
https://www.synology-forum.ru/index.php?/topic/10138--/
11 Злопчинский
 
28.03.22
13:51
а что на Ядиск заливать планируется?
не проще куда-нить на ФТП?
12 Damash
 
28.03.22
14:02
(3)(7) ок, спасибо
буду пробовать!
13 Damash
 
28.03.22
14:08
(7) спасибо, всё полетело.

итоговая процедура:

Процедура глЗагрузитьОбновитьФайлНаЯндексДиске(token, УрлКYandexDisk, overwrite, ПутьКФайлуДляЗагрузки) Экспорт     
    httpobj=CreateObject("winhttp.winhttprequest.5.1");
    httpobj.Open("GET",УрлКYandexDisk,0);
    httpobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    httpobj.setRequestHeader("Authorization","OAuth " + token);
    httpobj.Send("");
    Сообщить("1: "+УрлКYandexDisk); // папка на Я.Диске, куда требуется закачка
    Сообщить("2: "+httpobj.status+":"+httpobj.statusText);
    
    Текст=0;
    Текст=СоздатьОбъект("Текст");
    Текст=httpobj.ResponseText;
    Текст=СтрЗаменить(Текст,"{""href"":""h","h");
    ТехУрл=СтрЗаменить(Текст,"""}","");
    Сообщить("3: "+ТехУрл); //технический url для закачки на Я.Диск
    
    
    dataStream = СоздатьОбъект("ADODB.Stream");
    dataStream.Type = 1;
    dataStream.Open();
    dataStream.LoadFromFile(ПутьКФайлуДляЗагрузки);    
    
    
    httpobj.Open("PUT",ТехУрл,0);    
    httpobj.SetRequestHeader("Content-Type", "application/octet-stream");
    httpobj.Send(dataStream);
    Сообщить("4: "+httpobj.status+":"+httpobj.statusText);
    Сообщить("5: "+httpobj.ResponseText); //ответ о результате закачки    
    httpobj=0;
КонецПроцедуры
14 kupec
 
28.03.22
19:30
А что такое token?
15 MWWRuza
 
гуру
28.03.22
20:23
Токен - это строка символов, которая получается после авторизации через API по логину/паролю или как на некоторых сайтах(например, ЧЗ) по ЭЦП. Имеет какой-то ограниченный срок жизни, и используется в запросах, что-бы каждый раз логин/пароль/ЭЦП "не светить" - несколько утрированно объяснил, но по сути примерно так.

Кстати, вопрос к ТС - а не поделитесь процедуркой/функцией под 7.7 для получения токена ЯД - ? Вроде как сейчас и не надо, но... А вдруг понадобится? :-)
16 stix2010
 
28.03.22
21:33
(1) скорее всего файлы маленькие? 50 мб так не пройдет