Как отправить запрос POST через домен через JavaScript?
Заметки - он не должен обновлять страницу, и мне нужно впоследствии захватить и проанализировать ответ.
Ваша помощь с некоторыми примерами кода будет высоко оценена.
Как отправить запрос POST через домен через JavaScript?
Заметки - он не должен обновлять страницу, и мне нужно впоследствии захватить и проанализировать ответ.
Ваша помощь с некоторыми примерами кода будет высоко оценена.
Обновление:. Прежде чем продолжить, каждый должен прочитать и понять учебник html5rocks на CORS. Это легко понять и очень ясно.
Если вы управляете сервером POSTED, просто используйте "Cross-Origin Resource Sharing standard", установив заголовки ответов на сервере. Этот ответ обсуждается в других ответах в этой теме, но не очень четко, на мой взгляд.
Короче, вот как вы выполняете POST-перекрестный домен с сайта from.com/1.html на сайт to.com/postHere.php(используя PHP в качестве примера). Примечание. Вам нужно только установить Access-Control-Allow-Origin
для запросов NON OPTIONS
- этот пример всегда устанавливает все заголовки для меньшего фрагмента кода.
В настройке postHere.php выполните следующие действия:
switch ($_SERVER['HTTP_ORIGIN']) {
case 'http://from.com': case 'https://from.com':
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
break;
}
Это позволяет вашему script выполнять кросс-домен POST, GET и OPTIONS. Это станет ясно, когда вы продолжите читать...
Установите свой POST-адрес кросс-домена из JS (пример jQuery):
$.ajax({
type: 'POST',
url: 'https://to.com/postHere.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
Когда вы выполните POST на шаге 2, ваш браузер отправит на сервер метод "OPTIONS". Это "обнюхивание" браузером, чтобы узнать, прохладно ли сервер с вами, POSTing к нему. Сервер отвечает "Access-Control-Allow-Origin", сообщая браузеру "ОК" POST | GET | ORIGIN, если запрос возник из "http://from.com" или "https://from.com". Поскольку сервер в порядке с ним, браузер сделает второй запрос (на этот раз POST). Хорошей практикой является то, что ваш клиент задает тип контента, который он отправляет, - поэтому вам также необходимо это сделать.
В MDN есть отличная запись о управлении доступом HTTP, в которой подробно описывается, как работает весь поток. Согласно их документам, он должен "работать в браузерах, поддерживающих межсайтовый XMLHttpRequest". Однако это немного вводит в заблуждение, поскольку я думаю, что только современные браузеры допускают перекрестный домен POST. Я только подтвердил, что это работает с сафари, хром, FF 3.6.
Если вы это сделаете, помните следующее:
Если вы управляете удаленным сервером, вы, вероятно, должны использовать CORS, как описано в этом ответе; он поддерживается в IE8 и выше, а также во всех последних версиях FF, GC и Safari. (Но в IE8 и 9 CORS не позволит вам отправлять файлы cookie в запрос.)
Итак, если вы не контролируете удаленный сервер или вам нужно поддерживать IE7, или если вам нужны файлы cookie, и вам нужно поддерживать IE8/9, вы, вероятно, захотите использовать технику iframe.
Здесь пример кода; Я тестировал его на IE6, IE7, IE8, IE9, FF4, GC11, S5.
function crossDomainPost() {
// Add the iframe with a unique name
var iframe = document.createElement("iframe");
var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
document.body.appendChild(iframe);
iframe.style.display = "none";
iframe.contentWindow.name = uniqueString;
// construct a form with hidden inputs, targeting the iframe
var form = document.createElement("form");
form.target = uniqueString;
form.action = "http://INSERT_YOUR_URL_HERE";
form.method = "POST";
// repeat for each parameter
var input = document.createElement("input");
input.type = "hidden";
input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
Осторожно! Вы не сможете напрямую прочитать ответ POST, поскольку iframe существует в отдельном домене. Рамам не разрешено связываться друг с другом из разных доменов; это политика одного и того же происхождения.
Если вы управляете удаленным сервером, но вы не можете использовать CORS (например, потому, что вы работаете в IE8/IE9, и вам нужно использовать куки файлы), существуют способы работы с политикой одного и того же происхождения, например, используя window.postMessage
и/или один из нескольких библиотек, позволяющий отправлять междоменные межкадровые сообщения в старых браузерах:
Если вы не управляете удаленным сервером, вы не можете прочитать ответ POST, период. Это может привести к проблемам безопасности.
Псевдокод
var ifr = document.createElement('iframe');
var frm = document.createElement('form');
frm.setAttribute("action", "yoururl");
frm.setAttribute("method", "post");
// create hidden inputs, add them
// not shown, but similar (create, setAttribute, appendChild)
ifr.appendChild(frm);
document.body.appendChild(ifr);
frm.submit();
Вероятно, вы хотите, чтобы стиль iframe был скрытым и абсолютно позиционированным. Неверная пересылка сайта разрешена браузером, но если это так, то как это сделать.
Держите его простым:
междоменный POST:
используйте crossDomain: true,
не обновлять страницу:
Нет, он не будет обновлять страницу, так как вызов success
или error
async будет вызываться, когда сервер отправит ответ.
$.ajax({
type: "POST",
url: "http://www.yoururl.com/",
crossDomain: true,
data: 'param1=value1¶m2=value2',
success: function (data) {
// do something with server response data
},
error: function (err) {
// handle your error logic here
}
});
Если у вас есть доступ ко всем задействованным серверам, поместите в заголовок ответа для страницы, запрашиваемой в другом домене, следующее:
PHP:
header('Access-Control-Allow-Origin: *');
Например, в коде Drupal xmlrpc.php вы сделаете следующее:
function xmlrpc_server_output($xml) {
$xml = '<?xml version="1.0"?>'."\n". $xml;
header('Connection: close');
header('Content-Length: '. strlen($xml));
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/x-www-form-urlencoded');
header('Date: '. date('r'));
// $xml = str_replace("\n", " ", $xml);
echo $xml;
exit;
}
Вероятно, это создает проблему безопасности, и вы должны убедиться, что принимаете соответствующие меры для проверки запроса.
Проверьте функцию post_method
в http://taiyolab.com/mbtweet/scripts/twitterapi_call.js - хороший пример описанного выше метода iframe.
Создайте два скрытых iframes (добавьте "display: none;" в стиль css). Сделайте свой второй iframe точкой для чего-то в своем собственном домене.
Создайте скрытую форму, установите ее метод "post" с target = ваш первый iframe и, возможно, установите enctype в "multipart/form-data" (я думаю, вы хотите сделать POST, потому что хотите для отправки многостраничных данных, например изображений?)
Когда вы готовы, сделайте форму submit() POST.
Если вы можете получить другой домен для возврата javascript, который будет осуществлять междоменную связь с помощью iframe (http://softwareas.com/cross-domain-communication-with-iframes) то вам повезло, и вы также можете зафиксировать ответ.
Конечно, если вы хотите использовать свой сервер в качестве прокси-сервера, вы можете избежать всего этого. Просто отправьте форму на свой собственный сервер, который проксирует запрос другому серверу (при условии, что другой сервер не настроен для уведомления о несоответствиях в IP-адресах), получить ответ и вернуть все, что вам нравится.
Еще одна важная вещь, которую нужно отметить!!! В примере выше описано, как использовать
$.ajax({
type : 'POST',
dataType : 'json',
url : 'another-remote-server',
...
});
JQuery 1.6 и ниже имеет ошибку с междоменным XHR. Согласно Firebug, никаких запросов, кроме OPTIONS, не было отправлено. Нет POST. На всех.
Отработано 5 часов тестирования/настройки моего кода. Добавление большого количества заголовков на удаленном сервере (script). Без всякого эффекта. Но позже я обновил JQuery lib до 1.6.4, и все работает как шарм.
Если вы хотите сделать это в среде MVC ASP.net с помощью JQuery AJAX, выполните следующие действия: (это резюме решения, предложенного в этом потоке)
Предположим, что "caller.com" (может быть любым сайтом) необходимо отправить на "server.com" (приложение ASP.net MVC)
В приложении "server.com" Web.config добавьте следующий раздел:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
</customHeaders>
</httpProtocol>
На "server.com" у нас будет следующее действие на контроллере (называемом "Главная" ), на которое мы будем размещать:
[HttpPost]
public JsonResult Save()
{
//Handle the post data...
return Json(
new
{
IsSuccess = true
});
}
Затем из "caller.com" отправьте данные из формы (с идентификатором html "formId" ) на "server.com" следующим образом:
$.ajax({
type: "POST",
url: "http://www.server.com/home/save",
dataType: 'json',
crossDomain: true,
data: $(formId).serialize(),
success: function (jsonResult) {
//do what ever with the reply
},
error: function (jqXHR, textStatus) {
//handle error
}
});
Высокий уровень.... У вас должна быть установка cname на вашем сервере, чтобы other-serve.your-server.com указывал на other-server.com.
Ваша страница динамически создает невидимый iframe, который действует как ваш транспорт на other-server.com. Затем вам необходимо связаться через JS с вашей страницы на другом сервере и получить обратные вызовы, которые возвращают данные на вашу страницу.
Возможно, но требуется координация с сайта your-server.com и other-server.com
Это старый вопрос, но некоторые новые технологии могут помочь кому-то.
Если у вас есть административный доступ к другому серверу, вы можете использовать проект Forge с открытым исходным кодом, чтобы выполнить свой POST с междоменным доступом. Forge предоставляет кросс-доменную оболочку JavaScript XmlHttpRequest, которая использует API Flash raw socket. POST можно выполнить даже через TLS.
Причина, по которой вам нужен административный доступ к серверу, на который вы отправляете POST, является то, что вы должны предоставить междоменную политику, разрешающую доступ из вашего домена.
Я думаю, что лучший способ - использовать XMLHttpRequest (например, $.ajax(), $.post() в jQuery) с одним из полиномов совместного использования ресурсов Cross-Origin https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#wiki-CORS
У меня есть пример кода для этой проблемы.
http://reddymails.blogspot.com/2012/05/solving-cross-domain-problem-using.html
Есть еще один способ (с использованием функции html5). Вы можете использовать прокси-сервер iframe, размещенный в этом другом домене, вы отправляете сообщение с использованием postMessage в этот iframe, а затем iframe может выполнять запрос POST (в том же домене) и postMessage обратно с reposnse к родительскому окну.
parent on sender.com
var win = $('iframe')[0].contentWindow
function get(event) {
if (event.origin === "http://reciver.com") {
// event.data is response from POST
}
}
if (window.addEventListener){
addEventListener("message", get, false)
} else {
attachEvent("onmessage", get)
}
win.postMessage(JSON.stringify({url: "URL", data: {}}),"http://reciver.com");
iframe на reciver.com
function listener(event) {
if (event.origin === "http://sender.com") {
var data = JSON.parse(event.data);
$.post(data.url, data.data, function(reponse) {
window.parent.postMessage(reponse, "*");
});
}
}
// don't know if we can use jQuery here
if (window.addEventListener){
addEventListener("message", listener, false)
} else {
attachEvent("onmessage", listener)
}
Должно быть возможно с помощью пользовательской таблицы YQL + JS XHR, посмотрите: http://developer.yahoo.com/yql/guide/index.html
Я использую его, чтобы выполнить некоторую очистку HTML (js) html, отлично работает (У меня есть полный аудиоплеер, с поиском по интернету/плейлистам/текстам/последней информации fm, всем клиенту js + YQL)
Я знаю, что это старый вопрос, но я хотел поделиться своим подходом. Я использую cURL как прокси-сервер, очень простой и последовательный. Создайте страницу php с именем submit.php и добавьте следующий код:
<?
function post($url, $data) {
$header = array("User-Agent: " . $_SERVER["HTTP_USER_AGENT"], "Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
$url = "your cross domain request here";
$data = $_SERVER["QUERY_STRING"];
echo(post($url, $data));
Затем в js (jQuery здесь):
$.ajax({
type: 'POST',
url: 'submit.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
CORS для вас. CORS - это "перекрестный ресурс совместного использования ресурсов", это способ отправки запроса перекрестного домена. Теперь API XMLHttpRequest2 и Fetch поддерживают CORS и могут отправлять запросы POST и GET
Но он имеет свои пределы. Серверу требуется конкретное требование Access-Control-Allow-Origin, и его нельзя установить в '*'.
И если вы хотите, чтобы любое происхождение могло отправить запрос вам, вам нужен JSONP (также нужно установить Access-Control-Allow-Origin, но может быть '*')
Для большого количества запросов, если вы не знаете, как выбрать, я думаю, вам нужен полный функциональный компонент для этого. Позвольте мне представить простой компонент https://github.com/Joker-Jelly/catta
Если вы используете современный браузер ( > IE9, Chrome, FF, Edge и т.д.), очень рекомендую вам использовать простой, но красивый компонент https://github.com/Joker-Jelly/catta. Он не имеет никакой зависимости, менее 3 КБ, и он поддерживает Fetch, AJAX и JSONP с таким же сильным синтаксическим примером и параметрами.
catta('./data/simple.json').then(function (res) {
console.log(res);
});
Он также поддерживает весь способ импорта в ваш проект, например, модуль ES6, CommonJS и даже <script>
в HTML.