web-dev-qa-db-fra.com

Demande HTTP Ajax via la page HTTPS

Je vais avoir un site avec quelques pages sur la connexion HTTPS. À partir de ces pages HTTPS, je dois utiliser une requête HTTP Ajax pour la récupération d’erreurs telles que les champs vides. Mais ces messages d'erreur ne viennent pas. Existe-t-il une solution ou dois-je faire cette demande AJAX pour archiver la connexion HTTPS?

23
cooldude

Ceci n’est pas possible en raison de la Même politique d’origine

Vous devrez également basculer les demandes Ajax sur https.

35
Pekka 웃

Sans aucune solution côté serveur, Theres n’est qu’un des moyens par lequel une page sécurisée peut obtenir quelque chose d’une page/demande non sécurisée et c’est pensé postMessage et un popup

J'ai dit popup parce que le site n'est pas autorisé à mixer du contenu. Mais un popup ne mélange pas vraiment. Il a sa propre fenêtre mais peut toujours communiquer avec l'ouvreur avec postMessage.

Ainsi, vous pouvez ouvrir une nouvelle page http avec window.open(...) et demander à cette dernière de le faire (c'est-à-dire si le site utilise également CORS)


XDomain m’est venu à l’esprit lorsque j’ai écrit ceci, mais voici une approche moderne qui utilise le nouvel fetch api , l’avantage est le streaming de gros fichiers, l’inconvénient est que cela ne fonctionnera pas dans tous les navigateurs

Vous mettez ce script proxy sur n'importe quelle page 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()
  })
}

Ensuite, vous ouvrez une fenêtre contextuelle dans votre page https (notez que vous ne pouvez le faire que sur un événement d'interaction utilisateur, sinon celui-ci sera bloqué).

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

créez votre fonction utilitaire

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))
    }
  })
}

Et faites la requête comme vous le faites normalement avec le fetch api

xfetch('http://httpbin.org/get')
  .then(res => res.text())
  .then(console.log)
6
Endless

Néanmoins, cela peut être fait avec les étapes suivantes:

  1. envoyer une demande https ajax sur votre site web (le même domaine)

    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. obtenir une requête ajax, par exemple, par php, et créer une requête CURL à tout site Web souhaité via http.

    use linslin\yii2\curl;
    $curl = new curl\Curl();
    $curl->get('http://example.com');
    
4
Maxim Ilin

Dans certains cas, une demande unidirectionnelle sans réponse peut être envoyée à un serveur TCP, sans certificat SSL. Un serveur TCP, contrairement à un serveur HTTP, va capturer votre demande. Cependant, il n'y aura pas d'accès aux données envoyées à partir du navigateur, car celui-ci n'enverra aucune donnée sans vérification du certificat. Et dans des cas spéciaux, même un signal nu TCP sans aucune donnée suffit à exécuter certaines tâches. Par exemple, pour un périphérique IoT au sein d'un réseau local, vous pourrez établir une connexion avec un service externe. Lien

Il s’agit d’une sorte de déclencheur "Wake Up" qui fonctionne sur un port sans aucune sécurité.

Si une réponse est nécessaire, elle peut être implémentée à l'aide d'un serveur https public sécurisé, qui peut renvoyer les données nécessaires au navigateur, par exemple à l'aide de p. Ex. Websockets.

2
user2080851

Du javascript, j'ai essayé de plusieurs façons et je ne pouvais pas.

Vous avez besoin d'une solution côté serveur, par exemple sur c #. J'ai créé un contrôleur qui appelle le http, désérialise l'objet. Le résultat est que lorsque j'appelle à partir de javascript, je fais une demande à partir de mon https: // domaine à mon htpps: // domaine. S'il vous plaît voir mon code 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);
    }

Et laissez-moi vous montrer mon côté client (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) + ''
            );

        });       

});

Je souhaite que cela vous aide! Salutations

J'ai créé un module appelé cors-bypass , qui vous permet de le faire sans avoir besoin d'un serveur. Il utilise postMessage pour envoyer des événements inter-domaines, utilisés pour fournir des API HTTP factices (fetch, WebSocket, XMLHTTPRequest, etc.).

Il fait fondamentalement la même chose que la réponse de Endless , mais ne nécessite aucune modification de code pour pouvoir être utilisé.

Exemple d'utilisation:

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
samdd