Як я можу відправити HTTP POST-запит на сервер від Excel за допомогою VBA?


Відповіді:


147
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = "http://www.somedomain.com"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.send("")

Крім того, для більшого контролю над HTTP-запитом, який ви можете використовувати WinHttp.WinHttpRequest.5.1замість MSXML2.ServerXMLHTTP.


9
Для більшого контролю над HTTP-запитом ви можете використовувати "WinHttp.WinHttpRequest.5.1" замість "MSXML2.ServerXMLHTTP"
Меттью Мердок

5
Примітно те, що ви також можете використовувати це для видачі HTTP PUT, змінивши "POST" на "PUT". Вміст до PUT йде методом .send (). Будь-які додаткові заголовки, які вам потрібно встановити, можна також виконати за синтаксисом, використаним у прикладі User-Agent.
радиканд

7
Будь ласка, не використовуйте круглі дужки навколо параметрів, якщо ви не використовуєте значення повернення Sub: Синтаксис VBA не дозволяє дужки навколо параметрів Sub (вони потрібні для функцій), тому ці дужки є фактично арифметичними дужками, які використовуються для уточнення пріоритетності оператора. Крім введення в оману та незрозумілості, це може призвести до помилки виконання, якщо аргумент є об'єктом. І хоча це прямо не вимагається, зазвичай ви хочете використовувати відповідь HTTP, яку ви можете згадати, можна отримати objHTTP.responseText.
Левіафан

4
@Leviathan парени насправді роблять більше, ніж це: вони змушують час виконання VBA оцінювати вираз як значення та передають його методу ByVal незалежно від того, підпис методу говорить ByRefчи ні. Ось чому використання їх з об’єктними змінними типу, у якого немає учасника за замовчуванням, викликає помилки під час виконання; і використовуючи їх на об'єкті, який має член за замовчуванням, передає значення цього члена за замовчуванням замість фактичного об'єкта.
Матьє Гіндон

1
Мільйон разів дякую. Я не знаю чому, тому що я не бачив цього в жодних інших прикладах, але заголовок "Користувач-агент" був для мене вирішальним, тому що в іншому випадку тіло не було надіслано в моєму запиті.
redO жовтня13

51

Якщо він потрібен для роботи на Mac і Windows, ви можете використовувати QueryTables:

With ActiveSheet.QueryTables.Add(Connection:="URL;http://carbon.brighterplanet.com/flights.txt", Destination:=Range("A2"))
    .PostText = "origin_airport=MSN&destination_airport=ORD"
    .RefreshStyle = xlOverwriteCells
    .SaveData = True
    .Refresh
End With

Примітки:

  • Щодо виводу ... Я не знаю, чи можна повернути результати в ту саму клітинку, яка називала функцію VBA. У наведеному вище прикладі результат записується в A2.
  • Щодо введення даних ... Якщо ви хочете, щоб результати оновлювались при зміні певних комірок, переконайтеся, що ці клітини є аргументом вашої функції VBA.
  • Це не буде працювати в Excel для Mac 2008, на якому немає VBA. Excel для Mac 2011 повернув VBA.

Для отримання більш детальної інформації ви можете побачити моє повне резюме про " використання веб-служб від Excel ".


3
+1: мені це потрібно лише в Windows, але кросплатформенне рішення може принести користь комусь іншому.
Меттью Мердок

Я не думаю, що ви дійсно можете отримати доступ до html-коду, ви можете отримати інформацію лише на наданій веб-сторінці (не фактичний код html)
user1493046

1
+1 для кросплатформенного рішення та +1 (якщо я міг) для повного резюме з посиланням на суть та всі. Дякую!!
авіаудар

Мені довелося підтримувати і windows, і mac, і це рішення було правильно! Зауважте, що коли ви вказуєте PostText, URL повинен обробляти POST-запити, інакше він повинен обробляти GET-запити.
amolk

1
Чи можливо вивести результати на змінну замість діапазону? Потрібно зробити кілька Json розбору.
Станісладрг відновлює Моніку

42

Окрім прихильника Білла Ящера :

Більшість із загальних даних аналізують необроблені дані публікації. Наприклад, у PHP, у вас буде масив, $_POSTв якому будуть зберігатися окремі змінні в даних публікації. У цьому випадку вам потрібно використовувати додатковий заголовок "Content-type: application/x-www-form-urlencoded":

Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
URL = "http://www.somedomain.com"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
objHTTP.send ("var1=value1&var2=value2&var3=value3")

Інакше вам доведеться читати необроблені дані публікації на змінній "$HTTP_RAW_POST_DATA".


1
Я намагаюся опублікувати цей запит (з фігурними дужками) та отримати помилки компіляції ... Чи можете ви, будь ласка, допомогти: "{" запит ": {" carName ":" Honda "," model ":" 1A5 "}}"
скрипка

6

Ви можете використовувати ServerXMLHTTPв проекті VBA, додавши посилання на MSXML.

  1. Відкрийте редактор VBA (зазвичай, редагуючи макрос)
  2. Перейдіть до списку доступних посилань
  3. Перевірте Microsoft XML
  4. Натисніть кнопку ОК.

посилань на MSXML в рамках VBA-проектів )

Документація ServerXMLHTTP MSDN має повну інформацію про всі властивості і методи ServerXMLHTTP.

Якщо коротко, це працює в основному так:

  1. Виклик відкритого методу для підключення до віддаленого сервера
  2. Надіслати дзвінок, щоб надіслати запит.
  3. Прочитайте відповідь через responseXML , responseText , responseStream або responseBody

1
для цього посилання використовується jscript, а не VBA
Джон Генкель

1
Дякую @JohnHenckel Я вніс деякі зміни, щоб оновити цю відповідь.
Марк Бік

3

Щоб заповнити відповідь інших користувачів:

Для цього я створив об’єкт "WinHttp.WinHttpRequest.5.1" .

Надішліть запит на пошту з деякими даними від Excel за допомогою VBA:

Dim LoginRequest As Object
Set LoginRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
LoginRequest.Open "POST", "http://...", False
LoginRequest.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
LoginRequest.send ("key1=value1&key2=value2")

Надішліть запит на отримання аутентифікації маркера від Excel за допомогою VBA:

Dim TCRequestItem As Object
Set TCRequestItem = CreateObject("WinHttp.WinHttpRequest.5.1")
TCRequestItem.Open "GET", "http://...", False
TCRequestItem.setRequestHeader "Content-Type", "application/xml"
TCRequestItem.setRequestHeader "Accept", "application/xml"
TCRequestItem.setRequestHeader "Authorization", "Bearer " & token
TCRequestItem.send

Девід, як тільки ви відправляєте запит, як ви читаєте відповідь?
ps0604

Відповідь всередині TCRequestItem Object, ви можете прочитати її так: TCRequestItem.ResponseTextпісля цьогоTCRequestItem.send
Девід Q

0

Я робив це перед тим, як використовувати бібліотеку MSXML, а потім використовувати об’єкт XMLHttpRequest, дивіться тут .


1
Файл не знайдено.
SuShuang
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.