HTTP-запрос Ajax через страницу HTTPS - PullRequest
29 голосов
/ 27 октября 2010

У меня есть сайт с несколькими страницами по HTTPS-соединению. На этих страницах HTTPS я должен использовать HTTP-запрос Ajax для поиска некоторых ошибок, таких как пустые поля. Но это сообщения об ошибках не приходят. Есть ли какое-либо решение, или я должен сделать этот AJAX-запрос на файл по соединению HTTPS?

Ответы [ 6 ]

39 голосов
/ 27 октября 2010

Это невозможно из-за Одинаковой политики происхождения .

Вам также потребуется переключить запросы Ajax на https.

6 голосов
/ 06 июля 2017

Без какого-либо решения на стороне сервера, Theres - это только один способ, которым защищенная страница может получить что-то от небезопасной страницы / запроса, и это считается postMessage и всплывающее окно

Я сказал, что всплывающее окно, потому что сайт не может смешивать контент. Но всплывающее окно на самом деле не смешивается. У него есть собственное окно, но он все еще может общаться с открывателем с помощью postMessage.

Таким образом, вы можете открыть новую http-страницу с помощью window.open(...) и сделать это, сделав запрос за вас (то есть, если сайт также использует CORS)


XDomain пришел в голову, когда я написал это, но здесь есть современный подход, использующий новый fetch api , преимущество заключается в потоковой передаче больших файлов, недостатком является то, что он выиграл не работает во всех браузерах

Вы помещаете этот прокси-скрипт на любую http-страницу

onmessage = evt => {
  const port = evt.ports[0]

  fetch(...evt.data).then(res => {
    // the response is not clonable
    // so we make a new plain object
    const obj = {
      bodyUsed: false,
      headers: [...res.headers],
      ok: res.ok,
      redirected: res.redurected,
      status: res.status,
      statusText: res.statusText,
      type: res.type,
      url: res.url
    }

    port.postMessage(obj)

    // Pipe the request to the port (MessageChannel)
    const reader = res.body.getReader()
    const pump = () => reader.read()
    .then(({value, done}) => done 
      ? port.postMessage(done)
      : (port.postMessage(value), pump())
    )

    // start the pipe
    pump()
  })
}

Затем вы открываете всплывающее окно на своей странице https (обратите внимание, что вы можете сделать это только для события взаимодействия с пользователем, иначе оно будет заблокировано)

window.popup = window.open(http://.../proxy.html)

создайте свою служебную функцию

function xfetch(...args) {
  // tell the proxy to make the request
  const ms = new MessageChannel
  popup.postMessage(args, '*', [ms.port1])

  // Resolves when the headers comes
  return new Promise((rs, rj) => {

    // First message will resolve the Response Object
    ms.port2.onmessage = ({data}) => {
      const stream = new ReadableStream({
        start(controller) {

          // Change the onmessage to pipe the remaning request
          ms.port2.onmessage = evt => {
            if (evt.data === true) // Done?
              controller.close()
            else // enqueue the buffer to the stream
              controller.enqueue(evt.data)
          }
        }
      })

      // Construct a new response with the 
      // response headers and a stream
      rs(new Response(stream, data))
    }
  })
}

И сделайте запрос, как вы обычно делаете с fetch api

xfetch('http://httpbin.org/get')
  .then(res => res.text())
  .then(console.log)
5 голосов
/ 12 апреля 2017

Тем не менее, это можно сделать с помощью следующих шагов:

  1. отправить запрос https ajax на ваш веб-сайт (тот же домен)

    jQuery.ajax({
        'url'      : '//same_domain.com/ajax_receiver.php',
        'type'     : 'get',
        'data'     : {'foo' : 'bar'},
        'success'  : function(response) {
            console.log('Successful request');
        }
    }).fail(function(xhr, err) {
        console.error('Request error');
    });
    
  2. получите ajax-запрос, например, по php, и сделайте CURL-запрос на получение любого желаемого веб-сайта по http.

    use linslin\yii2\curl;
    $curl = new curl\Curl();
    $curl->get('http://example.com');
    
2 голосов
/ 10 апреля 2016

В некоторых случаях односторонний запрос без ответа может быть отправлен на сервер TCP без сертификата SSL.TCP-сервер, в отличие от HTTP-сервера, перехватит ваш запрос.Однако не будет доступа к любым данным, отправленным из браузера, потому что браузер не будет отправлять данные без проверки положительного сертификата.А в особых случаях даже голого TCP-сигнала без каких-либо данных достаточно для выполнения некоторых задач.Например, для устройства IoT в локальной сети, чтобы начать подключение к внешней службе. Link

Это своего рода триггер "пробуждения", который работает на порте без какой-либо защиты.

В случае необходимости ответа это может бытьреализовано с использованием защищенного публичного https-сервера, который может отправлять необходимые данные обратно в браузер, например, через Websockets.

0 голосов
/ 06 января 2019

Я создал модуль с именем cors-bypass, который позволяет вам делать это без необходимости в сервере.Он использует postMessage для отправки междоменных событий, который используется для предоставления фиктивных HTTP API (fetch, WebSocket, XMLHTTPRequest и т. Д.).выполняет те же действия, что и ответ от Endless , но не требует изменений кода для его использования.

Пример использования:

import { Client, WebSocket } from 'cors-bypass'

const client = new Client()

await client.openServerInNewTab({
  serverUrl: 'http://random-domain.com/server.html',
  adapterUrl: 'https://your-site.com/adapter.html'
})

const ws = new WebSocket('ws://echo.websocket.org')
ws.onopen = () => ws.send('hello')
ws.onmessage = ({ data }) => console.log('received', data)
0 голосов
/ 24 декабря 2017

Из javascript я пробовал несколькими способами и не смог.

Вам необходимо решение на стороне сервера, например, на c # Я создал контроллер, который вызывает http, и десериализует объект, и в результате я при вызове из javascript выполняю запрос от моего https://domain на мой домен htpps: //. Пожалуйста, смотрите мой код C #:

[Authorize]
public class CurrencyServicesController : Controller
{
    HttpClient client;
    //GET: CurrencyServices/Consultar?url=valores?moedas=USD&alt=json
    public async Task<dynamic> Consultar(string url)
    {
        client = new HttpClient();
        client.BaseAddress = new Uri("http://api.promasters.net.br/cotacao/v1/");
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        System.Net.Http.HttpResponseMessage response = client.GetAsync(url).Result;

        var FromURL = response.Content.ReadAsStringAsync().Result;

        return JsonConvert.DeserializeObject(FromURL);
    }

И позвольте мне показать вам мою клиентскую часть (Javascript)

<script async>
$(document).ready(function (data) {

    var TheUrl = '@Url.Action("Consultar", "CurrencyServices")?url=valores';
    $.getJSON(TheUrl)
        .done(function (data) {
            $('#DolarQuotation').html(
                '$ ' + data.valores.USD.valor.toFixed(2) + ','
            );
            $('#EuroQuotation').html(
                '€ ' + data.valores.EUR.valor.toFixed(2) + ','
            );

            $('#ARGPesoQuotation').html(
                'Ar$ ' + data.valores.ARS.valor.toFixed(2) + ''
            );

        });       

});

Я желаю, чтобы это помогло вам! Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...