如何在浏览器中通过POST请求加载外来图像?

时间:2015-05-14 08:59:29

标签: javascript ajax html5 image post

我的网络应用程序(HTML5 + JavaScript)需要显示由外国网络服务生成的PNG图像。

但是,该Web服务仅支持 POST请求。 (更准确地说,它确实提供了GET请求,但我必须传输大的参数,因此GET URL变得太长。)

此外,Web服务具有与Web应用程序不同的域,并且不提供正确的CORS头,因此Ajax(XMLHTTPRequest)不起作用。

我的Web应用程序是否仍然可以通过POST请求加载和显示外部图像?

我要求的解决方案与以下令人讨厌的解决方法不同,这些已经为我所熟知:

  • 没有设置翻译请求的本地代理(并且也绕过同源策略)
  • 不使用某些陌生人的远程代理
  • 不使用Flash
  • 不使用Java Applet
  • 不使用操作系统特定功能,如ActiveX控件

但是,无法使用Internet Explorer的解决方案是可以接受的。即使是Firefox或Chrome特定的解决方案也很受欢迎。

3 个答案:

答案 0 :(得分:6)

可怕的黑客:

将表单提交给iframe,并将图片显示在iframe中。

(但不要这样做,听起来网络服务器旨在避免将图像直接嵌入其他网站。)

答案 1 :(得分:0)

我有一些可能的解决方案......

解决方案1 ​​

如果您的图像小于25kb,您可以通过YQL执行以下操作:select * from data.uri where url="http://jquery.com/jquery-wp-content/themes/jquery/images/logo-jquery@2x.png"因此,您只需抓取base64图像并继续操作即可。要通过YQL进行POST,您应该添加and postdata="foo=foo&bar=bar"之类的内容{checker this article

警告:这种方法的表现可能并不好。从最终用户到YQL再到服务然后一直回头,有相当多的延迟。还有一些服务器端处理YQL对base64编码图像并提供一些JSON响应。

解决方案2

启用CORS或通过其他代理。一旦你这样做,如果你仍然无法获得base64数据,那么你需要做两件事。首先添加一个处理二进制文件的jQuery传输。第二个处理二进制blob并将其转换为base64。

这是我发现的jQuery Binary Transport

$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
   // check for conditions and support for blob / arraybuffer response type
    if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
    {
        return {
            // create new XMLHttpRequest
            send: function(headers, callback){
        // setup all variables
                var xhr = new XMLHttpRequest(),
        url = options.url,
        type = options.type,
        async = options.async || true,
        // blob or arraybuffer. Default is blob
        dataType = options.responseType || "blob",
        data = options.data || null,
        username = options.username || null,
        password = options.password || null;

                xhr.addEventListener('load', function(){
            var data = {};
            data[options.dataType] = xhr.response;
            // make callback and send data
            callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
                });

                xhr.open(type, url, async, username, password);

        // setup custom headers
        for (var i in headers ) {
            xhr.setRequestHeader(i, headers[i] );
        }

                xhr.responseType = dataType;
                xhr.send(data);
            },
            abort: function(){
                jqXHR.abort();
            }
        };
    }
});

添加传输后,您可以发出任何类型的AJAX请求。

$.ajax({
    type: "POST",
    url: 'http://myservice.com/service/v1/somethingsomething',
    dataType: 'binary',
    success: function(imgData) {
        var img = new Image(),
            reader = new window.FileReader();

        reader.readAsDataURL(imgData); 
        reader.onloadend = function() {
            img.src = reader.result
            $('#logo-events').append(img);
        }
    }
});

读者应该使用Blob并输出base64版本。当读者完成转换/读取时,它将创建并成像并将其附加到某处。 GET或POST应该不再重要。

答案 2 :(得分:0)

我发现了这个相关的问题:Post data to JsonP

我认为它适用于您的情况。

基本上,将您的jsonp请求发送到您的服务器(同源策略应该不是问题),并加载响应 var test = SitecoreContext.QuerySingle<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}"); var test1 = SitecoreContext.Query<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}").ToList(); var test2 = SitecoreContext.GetCurrentItem<Item>(); var test3 = SitecoreContext.GetItem<Item>("{7A6D933A-127B-4C08-B073-7C39F16EBD06}");

就像@ Quentin的回答一样,这个黑客使用(隐藏的)Iframe