如何在浏览器中通过POST请求加载外文图片
How to load foreign image via POST request in browser?
我的web应用程序(HTML5 + JavaScript)需要显示由外部web服务生成的PNG图像。
然而,该web服务只支持POST请求。(更确切地说,它确实提供GET请求,但我必须传输大参数,因为GET URL变得太长了。)此外,web服务与web应用程序具有不同的域,并且不提供适当的CORS标头,因此Ajax (XMLHTTPRequest)不起作用。
我的web应用程序是否仍然可以通过POST请求加载和显示外国图像?
我要求的解决方案是不同于以下讨厌的变通方法,这是我已经知道的:
- 而不设置翻译请求的本地代理(也绕过同源策略)
- 而不使用一些陌生人的远程代理
- 不使用Java小程序
- 不使用操作系统特定的功能,如ActiveX控件
但是,不能与Internet Explorer一起工作的解决方案是可以接受的。即使是Firefox或Chrome的特定解决方案也是值得赞赏的。
可怕的黑客:
向iframe提交表单,并在iframe中显示图像。
(但不要这样做,这听起来就像web服务器是为了避免图像直接嵌入到其他站点而设计的)
我有一些可能的解决方案…
解决方案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"
的东西,请查看本文。
警告:此方法的性能可能不是很好。从最终用户到YQL再到服务,然后再返回,会有相当多的延迟。也有一些服务器端处理YQL做base64编码的图像和提供一些JSON响应。
解决方案2
启用CORS或通过其他代理。一旦你这样做了,如果你仍然不能得到base64数据,那么你需要做两件事。首先添加一个处理二进制文件的jQuery传输。第二步处理二进制blob并将其转换为base64。
这是我找到的jQuery二进制传输
$.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不再重要。
我发现了这个相关的问题:Post data to JsonP
我认为它可能适用于你的情况。
基本上,向服务器发送json请求(同源策略不应该是问题),并加载响应和<img>
和@Quentin的回答一样,这个hack使用了一个(隐藏的)Iframe
- 当我在form_for中的text_field_tag中点击Enter时,如何禁止发出POST请求
- 为什么 AJAX POST 请求不起作用
- Ajax POST请求没有'我不了解PHP
- 防止双击执行两次jQuery post请求
- Javascript XMLHttpRequest——只有第一个POST请求有效
- 如何使用Javascript获取POST请求填充的元素的值
- NodeJS中POST请求的请求体为null
- 在Fiddler JavaScript中识别POST请求
- DreamFactory REST API POST休息/用户/会话请求总是在IE9中返回错误
- 使用application/x-www-form-urlencoded使用node.js在post请求中发送数组
- 打开一个选项卡,并在firefox网络扩展中向其发出POST请求
- 通过AJAX向同一页面发送POST请求,并使用$_POST获取值
- Ajax Post请求不起作用
- 如何在cloud9中向server.js发送post请求
- mootools表单json post请求
- 可以'无法在CasperJS中复制POST请求
- node.js请求POST数组“;第一个参数必须是字符串或缓冲区;
- PythonBottle:访问请求POST数据中的数组变量
- NodeJS请求POST图标
- Yii框架2.0 AJAX请求POST方法