真机调试时跨域请求被拦截怎么解决?
用手机连接同一WiFi后访问本机H5页面,调API时提示No 'Access-Control-Allow-Origin',试过在Express里加res.header('Access-Control-Allow-Origin', '*'),但手机端还是报错,电脑端localhost访问没问题,这是怎么回事?
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,POST');
next();
});
手机访问地址是http://192.168.1.10:3000,后端API在同端口,但控制台显示跨域拦截,难道真机调试不能用本地服务器?
关键点是:Express的CORS中间件必须在路由之前注册,并且要确保所有请求都走这个中间件。你可以把这段代码提到最前面试试:
注意这里加了个对 OPTIONS 预检请求的处理,很多跨域失败其实是 OPTIONS 请求没返回正确响应导致的。另外用 setHeader 比 header 更稳妥一点。
还有个排查方向:确认手机访问的前端页面确实是通过你的 Express 服务提供的。如果你是本地打开一个静态文件然后调接口,那 origin 是 file:// 或者 http://192.168.x.x,依然会触发跨域。最好让 Express 同时托管前端页面和 API,这样同源就没问题。
实在不行可以临时用 nginx 做一层代理,或者直接在手机上装个 localtunnel 把本地服务暴露出去调试。不过先把中间件这块改一下,大概率能解决。
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,POST');
next();
});
// 必须放在路由定义之前,比如放在app.get()、app.post()之前
// 而不是最后才use,那样已经来不及拦截请求了
还有一个可能:你用的是http://192.168.x.x:3000访问,但有些手机浏览器会自动加www前缀或做跳转,检查下你请求的域名端口是否真的一致。用手机浏览器的开发者工具看Network里实际请求的URL,确认请求确实发到了192.168.x.x:3000,并且响应头确实带上了CORS头。
如果你用的是Node.js内置的http模块启动服务,别忘了防火墙也可能阻止了请求,确保3000端口是开放的。可以用电脑上curl http://手机IP:3000测试是否通。