前端怎么解决跨域问题
跨域问题本质上是前端浏览器的一种安全策略,叫同源策略。解决它规定:只有协议、跨域域名、问题端口完全一致的前端页面之间,才能自由读写资源。解决这策略本身没错,跨域但实际开发中,问题前端要调后端接口,前端后端在A服务器,解决前端页面在B服务器,跨域端口还不一样——跨域就这么发生了。问题
我见过不少刚入行的前端同事,一遇到跨域就慌,解决第一反应是跨域“关掉浏览器安全设置”。这法子治标不治本,用户那边可不会帮你关。真正靠谱的方案,得从请求链路上去想。
最简单的场景,后端接口是你自己团队的。那直接让后端在响应头里加一行Access-Control-Allow-Origin: *,或者指定你的前端域名。这叫CORS,跨域资源共享。浏览器发现响应头里有这个字段,就放行了。注意,如果请求带了自定义头或者用了Content-Type: application/json,浏览器会先发一个OPTIONS预检请求,后端得把这个也处理掉,否则照样报错。这个细节坑过很多人,我调过的接口里,十有八九是忘了处理预检。
但后端接口不在你手里呢?比如你接的是第三方开放平台。这时候可以走代理。开发环境下,用webpack的devServer配个proxy,把/api开头的请求转发到目标服务器。浏览器只跟你的devServer通信,同源,不跨。生产环境更简单,让Nginx配一条反向代理规则,把特定路径转发到上游接口。这种方式的好处是前端代码完全不用动,改改配置就行。
还有一种老派但有效的办法——JSONP。原理是利用<script>标签不受同源策略限制的特性,动态创建一个script标签,src指向带callback=xxx参数的接口地址。后端返回的是一段JavaScript代码,把数据塞进xxx(data)这个函数调用里。前端提前定义好xxx函数,数据就到了。但这方案有个硬伤:只支持GET请求。现在RESTful接口动不动就POST、PUT,所以JSONP基本退居二线了,除非你在维护老系统。
再提一个容易忽略的点——document.domain。这招只在主域相同的情况下管用,比如a.example.com和b.example.com,两边都设置document.domain = 'example.com',就能互相访问了。但它解决不了端口不同的问题,局限性很大,我工作这么久,实际用到的次数一只手数得过来。
说到个人经验,我强烈建议团队在项目初期就定好跨域方案,别等联调时才手忙脚乱。如果你前后端都是自己人,直接上CORS,后端加个配置类,一劳永逸。如果你控制不了后端,老老实实用Nginx或Node中间层做代理。最忌讳的是前端代码里写死某个跨域接口地址,然后临时用浏览器插件糊弄过去——这种代码一旦上线,必炸。
另外,跨域不只是“调不通”那么简单。有时候请求发出去了,后端也处理了,但浏览器把响应拦了,前端拿不到数据。这种情况排查起来最费劲,因为后端日志显示一切正常。解决办法是看浏览器Network面板里的响应信息,如果CORS头缺失,后端补上就行。
最后说个冷门但实用的场景——本地开发调试线上接口。你本地起的服务是localhost:8080,线上接口是https://api.example.com,这必然跨域。别慌,用CORS代理服务,比如https://cors-anywhere.herokuapp.com/这类,把接口地址拼在后面,代理帮你转发。当然,生产环境千万别这么干,这玩意儿只适合临时调试。
跨域不是玄学,是浏览器定下的规矩。你顺着它的规则走,要么让后端点头(CORS),要么绕道走(代理),要么利用漏洞(JSONP)。选哪种,取决于你对后端代码的控制力。记住一条:别想着绕过浏览器,那只会让你陷入更深的坑。
本文地址:http://www.79wt.cn/news/1170f399879.html
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。