通过HTTPS页面的HTTP Ajax请求

coo*_*ude 30 javascript ajax

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

Pek*_*ica 41

由于同源策略,这是不可能的.

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

  • 即使是跨源资源共享的工作草案也不可能:http://www.w3.org/TR/cors/#user-agent-security (2认同)
  • @NickSotiros 你为什么不希望它安全?缺点是零,HTTPS 页面上的 HTTP 请求可能会受到 MITM 攻击,注入恶意 JS。 (2认同)
  • @ceejayoz 好吧,如果你下载一个 js 脚本并执行它,你可能会受到 MITM 的攻击。但如果你只是想在 CSS 中使用别人的背景图片或下载 YouTube 视频,则不能。为什么浏览器假设通过 ajax 请求加载的内容将由 javascript 执行?有一个网站 https://prezi.com,它允许您使用从外部资源提取的在线内容生成在线演示文稿,它们必须使用代理。 (2认同)
  • @NickSotiros 实际上有人的 css 可以挂钩输入并将这些输入中输入的所有数据发送到坏服务器。 (2认同)

End*_*ess 6

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

我说popup因为网站不允许混合内容.但弹出窗口并没有真正混合.它有自己的窗口,但仍然可以通过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()
  })
}
Run Code Online (Sandbox Code Playgroud)

然后在https页面中打开一个弹出窗口(请注意,您只能在用户交互事件中执行此操作,否则将被阻止)

window.popup = window.open(http://.../proxy.html)
Run Code Online (Sandbox Code Playgroud)

创建你的效用函数

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))
    }
  })
}
Run Code Online (Sandbox Code Playgroud)

像通常使用fetch api一样发出请求

xfetch('http://httpbin.org/get')
  .then(res => res.text())
  .then(console.log)
Run Code Online (Sandbox Code Playgroud)

  • @Chiwda 不,因为您将安全内容与不安全内容混合在一起,所以使用弹出窗口并不混合 (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');
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 例如,通过php获取ajax请求,并通过http向任何所需的网站发出CURL获取请求。

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