通过HTTPS页面的HTTP Ajax请求

时间:2010-10-27 10:16:10

标签: javascript ajax

我的网站上有一些关于HTTPS连接的页面。从这些HTTPS页面,我必须使用HTTP Ajax请求进行一些错误检索,如空白字段。但是这个错误消息不会出现。是否有任何解决方案,或者我必须将该AJAX请求发送到HTTPS连接上?

7 个答案:

答案 0 :(得分:38)

由于Same Origin Policy,这是不可能的。

您还需要将Ajax请求切换为https。

答案 1 :(得分:6)

没有任何服务器端解决方案,Theres只是安全页面可以从不安全的页面/请求中获取内容的一种方式,并且认为是postMessage和弹出窗口

我说popup因为网站不允许混合内容。但弹出窗口并没有真正混合。它有自己的窗口,但仍然可以通过postMessage与开启者通信。

因此,您可以使用window.open(...)打开一个新的http页面并为您提出请求(即如果该网站也使用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)

答案 2 :(得分:5)

不过,这可以通过以下步骤完成:

  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. 例如,通过php获取ajax请求,并通过http向任何所需网站发送CURL get请求。

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

答案 3 :(得分:2)

在某些情况下,没有响应的单向请求可以在没有SSL证书的情况下触发到TCP服务器。与HTTP服务器相比,TCP服务器将捕获您的请求。但是,将无法访问从浏览器发送的任何数据,因为如果没有正面的证书检查,浏览器将不会发送任何数据。在特殊情况下,即使没有任何数据的裸TCP信号也足以执行某些任务。例如,LAN中的IoT设备可以启动与外部服务的连接。 Link

这是一种“唤醒”触发器,可以在没有任何安全性的端口上运行。

如果需要响应,可以使用安全的公共https服务器来实现,该服务器可以使用例如,将所需数据发送回浏览器。的WebSockets。

答案 4 :(得分:1)

在server.js中绕过API。这对我有用。

.nav-link

然后使用axios或类似的代码进行调用:

const navToggle = document.querySelector('.nav-toggle')
// replace this with something more sensible
const navLinkParent = document.querySelector('.nav-link').parentElement;

navToggle.addEventListener('click', () => {
    document.body.classList.toggle('nav-open')
})

// this is adding a click listener to ONE element
navLinkParent.addEventListener('click', (event) => {
  // check if the clicked element matches what you're after
  if (event.target.classList.contains('nav-link')) {
    document.body.classList.remove('nav-open')
  }
})

答案 5 :(得分:0)

我从几个方面尝试过的javascript,但我不能。

你需要一个服务器端解决方案,例如在c#上我创建了一个调用http的控制器,反序列化了对象,结果是当我从javascript调用时,我正在从我的{ {3}}到我的htpps://域名。请参阅我的c#代码:

.htaccess

让我告诉你我的客户端(Javascript)

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

我希望这对你有所帮助! 问候

答案 6 :(得分:0)

我已经创建了一个名为cors-bypass的模块,该模块无需服务器即可执行此操作。它使用postMessage发送跨域事件,该事件用于提供模拟HTTP API(fetchWebSocketXMLHTTPRequest等)。

从根本上讲,它与answer by 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)