ti-enxame.com

Carregando o endpoint de domínio cruzado com jQuery AJAX

Eu estou tentando carregar uma página HTML de cross-domain usando AJAX mas a menos que o dataType é "jsonp" não consigo obter uma resposta. No entanto, usando jsonp, o navegador está esperando um script tipo mime, mas está recebendo "text/html".

Meu código para o pedido é:

$.ajax({
    type: "GET",
    url: "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&[email protected]&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute",
    dataType: "jsonp",
}).success( function( data ) {
    $( 'div.ajax-field' ).html( data );
});

Existe alguma maneira de evitar o uso do jsonp para o pedido? Eu já tentei usar o parâmetro crossDomain, mas não funcionou.

Se não há alguma maneira de receber o conteúdo html no jsonp? Atualmente, o console está dizendo "inesperado <" na resposta jsonp.

114
xonorageous

jQuery Ajax Notes

  • Devido a restrições de segurança do navegador, a maioria das solicitações Ajaxestão sujeitas à mesma política de Origem ; a solicitação não pode recuperar com êxito dados de um domínio, subdomínio, porta ou protocolo diferente.
  • As solicitações de script e JSONP não estão sujeitas às mesmas restrições de política de origem.

Existem algumas maneiras de superar a barreira cross-domain:

Existem alguns plugins que ajudam com cross-domain requests:

Atenção!

A melhor maneira de superar este problema, é criar seu próprio proxy no back-end, para que seu proxy aponte para os serviços em outros domínios, porque no back-end não existe o mesma política de origem restrição. Mas se você não puder fazer isso no back-end, preste atenção nas dicas a seguir.


Aviso!

Usar proxies de terceiros não é uma prática segura, pois eles podem rastrear seus dados, para que possam ser usados ​​com informações públicas, mas nunca com dados privados.


Os exemplos de código mostrados abaixo usam jQuery.get () e jQuery.getJSON (), ambos são métodos abreviados de jQuery.ajax ()


CORS em qualquer lugar

O CORS Anywhere é um proxy node.js que adiciona cabeçalhos CORS ao pedido com proxy.
Para usar a API, basta prefixar o URL com o URL da API. (Suporta https: veja repositório github )

Se você quiser ativar automaticamente as solicitações entre domínios quando necessário, use o seguinte snippet:

$.ajaxPrefilter( function (options) {
  if (options.crossDomain && jQuery.support.cors) {
    var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
    options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
    //options.url = "http://cors.corsproxy.io/url=" + options.url;
  }
});

$.get(
    'http://en.wikipedia.org/wiki/Cross-Origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


Seja qual for a origem

Whatever Origin é um acesso cross domain jsonp. Esta é uma alternativa de código aberto para anyorigin.com .

Para buscar os dados de google.com, você pode usar este snippet:

// It is good specify the charset you expect.
// You can use the charset you want instead of utf-8.
// See details for scriptCharset and contentType options: 
// http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
$.ajaxSetup({
    scriptCharset: "utf-8", //or "ISO-8859-1"
    contentType: "application/json; charset=utf-8"
});

$.getJSON('http://whateverorigin.org/get?url=' + 
    encodeURIComponent('http://google.com') + '&callback=?',
    function (data) {
        console.log("> ", data);

        //If the expected response is text/plain
        $("#viewer").html(data.contents);

        //If the expected response is JSON
        //var response = $.parseJSON(data.contents);
});


CORS Proxy

O CORS Proxy é um simples proxy node.js para ativar a solicitação do CORS para qualquer site. Ele permite que o código javascript do seu site acesse recursos em outros domínios que normalmente seriam bloqueados devido ao mesmo Política de origem.

Como funciona? O CORS Proxy aproveita o Compartilhamento de Recursos entre Origens, que é um recurso que foi adicionado junto com o HTML 5. Os servidores podem especificar que desejam que os navegadores permitam que outros sites solicitem recursos que hospedam. O CORS Proxy é simplesmente um Proxy HTTP que adiciona um cabeçalho às respostas dizendo "qualquer um pode solicitar isso".

Esta é outra maneira de alcançar o objetivo (veja www.corsproxy.com ). Tudo o que você precisa fazer é remover http: // e www. Da URL que está sendo intermediada por proxy e prefixar a URL com www.corsproxy.com/

$.get(
    'http://www.corsproxy.com/' +
    'en.wikipedia.org/wiki/Cross-Origin_resource_sharing',
    function (response) {
        console.log("> ", response);
        $("#viewer").html(response);
});


Navegador de proxy CORS

Recentemente eu encontrei este, envolve vários utilitários orientados à segurança Cross Origin Remote Sharing. Mas é uma caixa preta com o Flash como backend.

Você pode vê-lo em ação aqui: CORS proxy browser
Obtenha o código fonte no GitHub: koto/cors-proxy-browser

211
jherax

Você pode usar o Ajax-cross-Origin um plugin jQuery. Com este plugin você usa o domínio cruzado jQuery.ajax(). Ele usa os serviços do Google para conseguir isso:

O AJAX O plug-in Cross Origin usa o Script do Google Apps como um proxy jSON Getter, em que jSONP não é implementado. Quando você define a opção crossOrigin Como true, o plug-in substitui o URL original pelo endereço do Google Script E o envia como parâmetro de URL codificado. O Script do Google Usa os recursos do Google Servers para obter os dados remotos e Retorna-os ao cliente como JSONP.

É muito simples de usar:

    $.ajax({
        crossOrigin: true,
        url: url,
        success: function(data) {
            console.log(data);
        }
    });

Você pode ler mais aqui: http://www.ajax-cross-Origin.com/

19
Ninioe

Se o site externo não suportar JSONP ou CORS, sua única opção é usar um proxy.

Crie um script no seu servidor que solicite esse conteúdo e, em seguida, use jQuery ajax para acessar o script em seu servidor.

10
Kevin B

Basta colocar isso no cabeçalho da sua página PHP e ele funcionará sem API:

header('Access-Control-Allow-Origin: *'); //allow everybody  

ou

header('Access-Control-Allow-Origin: http://codesheet.org'); //allow just one domain 

ou 

$http_Origin = $_SERVER['HTTP_Origin'];  //allow multiple domains

$allowed_domains = array(
  'http://codesheet.org',
  'http://stackoverflow.com'
);

if (in_array($http_Origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_Origin");
}
3
studio-klik

Para obter o site externo de formulário de dados passando usando um proxy local como sugerido por jherax você pode criar uma página php que busca o conteúdo para você a partir do respectivo URL externo e enviar uma requisição get para aquela página php.

var req = new XMLHttpRequest();
req.open('GET', 'http://localhost/get_url_content.php',false);
if(req.status == 200) {
   alert(req.responseText);
}

como um proxy php você pode usar https://github.com/cowboy/php-simple-proxy

0
Nitigya Sharma

Estou postando isso no caso de alguém enfrentar o mesmo problema que estou enfrentando agora. Eu tenho uma impressora térmica Zebra, equipada com o servidor de impressão ZebraNet, que oferece uma interface de usuário baseada em HTML para editar várias configurações, ver o status atual da impressora, etc. Preciso obter o status da impressora, que é exibida em uma dessas páginas html, oferecidas pelo servidor ZebraNet e, por exemplo, alertar () uma mensagem para o usuário no navegador. Isso significa que eu tenho que pegar essa página html em JavaScript primeiro. Embora a impressora esteja dentro da LAN do PC do usuário, essa mesma política de origem ainda continua firme no meu caminho. Eu tentei JSONP, mas o servidor retorna html e eu não encontrei uma maneira de modificar sua funcionalidade (se eu pudesse, eu já teria configurado o cabeçalho mágico Access-control-allow-Origin: *). Então eu decidi escrever um pequeno aplicativo de console em C #. Tem que ser executado como Admin para funcionar corretamente, caso contrário, trolls: D uma exceção. Aqui está algum código:

// Create a listener.
        HttpListener listener = new HttpListener();
        // Add the prefixes.
        //foreach (string s in prefixes)
        //{
        //    listener.Prefixes.Add(s);
        //}
        listener.Prefixes.Add("http://*:1234/"); // accept connections from everywhere,
        //because the printer is accessible only within the LAN (no portforwarding)
        listener.Start();
        Console.WriteLine("Listening...");
        // Note: The GetContext method blocks while waiting for a request. 
        HttpListenerContext context;
        string urlForRequest = "";

        HttpWebRequest requestForPage = null;
        HttpWebResponse responseForPage = null;
        string responseForPageAsString = "";

        while (true)
        {
            context = listener.GetContext();
            HttpListenerRequest request = context.Request;
            urlForRequest = request.RawUrl.Substring(1, request.RawUrl.Length - 1); // remove the slash, which separates the portNumber from the arg sent
            Console.WriteLine(urlForRequest);

            //Request for the html page:
            requestForPage = (HttpWebRequest)WebRequest.Create(urlForRequest);
            responseForPage = (HttpWebResponse)requestForPage.GetResponse();
            responseForPageAsString = new StreamReader(responseForPage.GetResponseStream()).ReadToEnd();

            // Obtain a response object.
            HttpListenerResponse response = context.Response;
            // Send back the response.
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseForPageAsString);
            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;
            response.AddHeader("Access-Control-Allow-Origin", "*"); // the magic header in action ;-D
            System.IO.Stream output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            // You must close the output stream.
            output.Close();
            //listener.Stop();

Tudo o que o usuário precisa fazer é executar o aplicativo do console como Admin. Eu sei que é muito ... frustrante e complicado, mas é uma espécie de solução para o problema da Diretiva de Domínio, caso você não possa modificar o servidor de forma alguma.

editar: de js eu faço uma chamada ajax simples:

$.ajax({
                type: 'POST',
                url: 'http://LAN_IP:1234/http://google.com',
                success: function (data) {
                    console.log("Success: " + data);
                },
                error: function (e) {
                    alert("Error: " + e);
                    console.log("Error: " + e);
                }
            });

O html da página solicitada é retornado e armazenado na variável data.

0
user2177283

Sua URL não funciona atualmente, mas seu código pode ser atualizado com esta solução de trabalho:

var url = "http://saskatchewan.univ-ubs.fr:8080/SASStoredProcess/do?_username=DARTIES3-2012&[email protected]&_program=%2FUtilisateurs%2FDARTIES3-2012%2FMon+dossier%2Fanalyse_dc&annee=2012&ind=V&_action=execute";

url = 'https://google.com'; // TEST URL

$.get("https://images"+~~(Math.random()*33)+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURI(url), function(data) {
    $('div.ajax-field').html(data);
});
<div class="ajax-field"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

0
350D