[TOC]
前言
最近使用 Creator 写游戏,用遇到跨域问题。
一个是使用 XMLHttpRequest,直接获取时提示跨域。
另一个 cc.loader.load 加载外部图片,显示图片的时候。
纠结了很久,最后只能通过服务器转发来实现。
过程
服务器转发
这里实用 php 实现,建立一个 php 文件,加入以下代码:
<?php
header("Content-Type: text/html;charset=utf-8");
header("Access-Control-Allow-Origin: *");
$url = $_GET['url'];
echo file_get_contents($url);
?>
这个文件的作用其实就是帮我访问 url,再把数据回给我。
XMLHttpRequest
把我需要 get 的 url,传递到 php 文件里面,让它替我访问
get: function (state, sender)
{
var url = this.httpUrl + state + '?';
url += sender;
var xhr = new XMLHttpRequest();
cc.info(url);
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400))
{
var response = xhr.responseText;
console.log(response);
var jsonObj = JSON.parse(response);
console.log(jsonObj);
}
};
xhr.timeout = 5000;
xhr.open("GET", url, true);
xhr.send();
},
其中 httpUrl 为 http://127.0.0.1/ky/?url=http://10.0.0.99/images/default.jpg
,
加载网络图片
这时 php 转发的其实是图片的字节流。
字节流创建 texture2d,texture2d 就能创建 spriteframe 对象。
var url = 'http://127.0.0.1/ky/?url=http://10.0.0.99/images/default.jpg';
var img = new Image();
img.src = url;
// img.crossOrigin = '';//Anonymous
img.crossOrigin = 'Anonymous';
img.onload = function()
{
var texture = new cc.Texture2D();
texture.generateMipmaps = false;
texture.initWithElement(img);
texture.handleLoadedTexture();
var newframe = new cc.SpriteFrame(texture);
this.TestNode.getComponent(cc.Sprite).spriteFrame = newframe;
} .bind(this);
调整 2016.12.06
通过以上的方法是可以在 Canvas 下获取图片与数据,不过在 WebGL 下获取图片有时候仍然会有问题。
只能改成用 base64 的方法显示图片。
首先要先修改服务器转发:
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type:text/html;charset=utf-8");
// header("Content-Type: image/jpeg;text/html; charset=utf-8");
//禁用错误报告
// error_reporting(0);
//报告运行时错误
// error_reporting(E_ERROR | E_WARNING | E_PARSE);
//报告所有错误
// error_reporting(E_ALL);
$url = @$_GET['url'];
foreach($_GET as $key=>$value){
if($key != 'url')
$url = $url.'&'.$key.'='.@$_GET[$key];
}
if (is_null($url)) {
return;
}
$isImage = false;
if (strpos($url, '.jpg') !== false) {
$isImage = true;
$img_type = 'jpg';
} else {
if (strpos($url, '.png') !== false) {
$isImage = true;
$img_type = 'png';
} else {
if (strpos($url, '.gif') !== false) {
$isImage = true;
$img_type = 'gif';
}
}
}
$curlHandle = curl_init();
curl_setopt($curlHandle, CURLOPT_URL, $url);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 30);
if ($isImage) {
$hearders = get_headers($url, 1);
if (preg_match('/200/', $hearders[0])) {
$content = @curl_exec($curlHandle);
curl_close($curlHandle);
if (!is_null($content)) {
echo 'data:image/' . $img_type . ';base64,' . base64_encode($content);
}
}
} else {
$content = @curl_exec($curlHandle);
curl_close($curlHandle);
if (!is_null($content) && !is_null(json_decode($content))) {
echo $content;
}
}
客户端生成 spriteFrame:
getSpriteFrame2: function (url, successCb, failureCb, target, otherSender) {
url = this.kyHelper + url;
var xhr = new XMLHttpRequest();
Tools.log(url);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
var response = xhr.responseText;
Tools.log(response);
var img = new Image();
img.src = response;
var texture = new cc.Texture2D();
// texture.generateMipmaps = false;
texture.initWithElement(img);
texture.handleLoadedTexture();
var newframe = new cc.SpriteFrame(texture);
if (successCb != null)
successCb.apply(target, [newframe, otherSender]);
} else {
if (failureCb != null)
failureCb.apply(target);
}
};
xhr.timeout = 5000;
xhr.open("GET", url, true);
xhr.send();
},