/ 开发笔记

H5游戏的客户端和服务端如何进行跨域调试?

问题背景

H5游戏在于服务端进行联调时,为了提高调试效率,通常不会将他们按照生产环境部署,而是会将游戏的客户端和服务端直接部署在开发机上,方便定位问题,甚至在遇到问题直接修改代码查看效果。

例如,
客户端如果用Cocos Creator开发的话,在调试时,默认运行在
http://localhost:7457/

而服务端代码,要么跑在服务端开发人员的机器上,或者由客户端开发下载后在本地运行,可能会运行在
http://localhost:8080/

如果直接从客户端访问服务端的接口,则会出现跨域的问题:
CocosCreator_cross_origin_01

Access to XMLHttpRequest at 'localhost:8080/login' from origin 'http://localhost:7457' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https

什么是CORS policy

参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

CORS 全称是 Cross-Origin Resource Sharing,跨域资源分享。

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin.

它是指通过设置指定的header,告知浏览器部署在一个域(origin)的web应用,正在访问另一个域上的资源。

mozilla_CORS

解决方法

1. 在服务端开启跨域访问

只需要在服务端代码中,返回的response中添加 header:

Access-Control-Allow-Origin: *

以beego为例实现跨域访问,只需要在Controller类中加入以下代码:

this.Ctx.Output.Header("Access-Control-Allow-Origin", "*")
this.ServeJSON()

如果希望只允许特定的客户端访问,则可以用指定的domain来替换"*", 例如

Access-Control-Allow-Origin: https://foo.example

注意

值得注意的地方是,如果你像我一样,把客户端和服务端都运行在本地,那么,开启跨域访问后,通过Chrome来调试,运行时可能还是不行,那么你可以试试把服务端的地址从localhost 替换成 127.0.0.1

CocosCreator_cross_origin_02

2. 通过反向代理,让客户端和服务端运行到同一个域上

既然不在同一个域上,那就想办法让他们“运行”在同一个域上,这可以通过反向代理的方式实现。

以Nginx为例,在nginx的配置文件(mac上,默认在 /usr/local/etc/nginx/nginx.conf)

# 服务端
location /gameserver/ {
	rewrite ^/gameserver(/.*)$ $1 break;
    proxy_pass http://localhost:8080;
}

# 客户端
location /game/ {
	rewrite ^/game(/.*)$ $1 break;
    proxy_pass http://localhost:7457;
}

然后,通过浏览器访问 http://localhost:8888/game/ 就可以正常调试了。