前端入门中,如果有理解错误请指教。
最近做了一个前后端分离的应用,后端 Java,前端 React ( Router,Hook ),部署在同一台服务器上的不同端口(后端 8080,前端 8081 )。
React 某个页面用 axios 向 8080 端口的 API 发送 Get 请求时,因为没做 CORS 设置,显示连接被拒绝。浏览器控制台显示是从服务器的 ip:8081 发起向服务器 ip:8080 的请求,但是我理解 html 和 js 不是运行在用户的浏览器环境里的吗,网络请求也应该是由浏览器发起的,这样发送的 Get 请求的源地址不应该是我自己电脑的 ip 地址?
所以 axios 是在服务端( node 启动那里)运行的吗,这样如果多个用户同时访问前端并发送请求,不就无法通过 ip 和端口来区分了?
1
yuang 2020-05-11 19:49:02 +08:00 via Android 2
axios 只是发出请 XMLRequest 并处理响应,请求本身是在后端完成的。请求实际是完成了的,只是浏览器跨域了,把结果给屏蔽了
|
2
yhxx 2020-05-11 20:19:37 +08:00 1
盲猜你的前端是在服务器上运行类似 npm run dev 的命令从而通过 8081 端口提供访问?
如果是这样的话,你可能需要调整一下 用户应该通过 80 或者 443 端口访问静态资源 |
3
crystom 2020-05-11 20:26:42 +08:00 1
只是理解问题,那个报错并不是指 http 请求从服务器的 ip:8081 发起向服务器 ip:8080,而是指当前页面和请求在不同域,所以浏览器给你屏蔽了
|
4
windychen0 2020-05-11 21:07:39 +08:00 1
.html 和 js 文件已经被下载到客户的浏览器上了,所以请求是从客户机到你的 8080 端口,req 里 origin 只是告诉你请求从哪个地址发起的,这个是可以伪造的,至于区分问题,http 本身是无状态协议,想要区分只能靠后端发的证书,比如 token 或者 cookie 证明,顺便说下 2 楼答的没在点子上,端口不是必须的,只是约定俗成的
|
5
1oNflow OP |
6
1oNflow OP @windychen0 感谢,这下搞懂了
|
7
enrio 2020-05-12 09:03:17 +08:00 1
要看你是用哪种开发方式,如果是开发阶段,你的前端发送一个接口请求,这时候地址是你的 node 服务器,然后 node 作为一个代理,再把这个请求发给你的后端,后端响应 node,node 再响应前端。如果是生产阶段,是没有 node 服务器这一层的,最终的结果就是一些静态文件,需要你放在 nginx 这种 web 服务器之中使用,这时候的接口调用请求就是直接到后端服务器。其实为了规避跨域的问题,我们一般会使用 nginx 的反向代理来实现接口的调用,从前端看起来端口还是 web 服务器的端口。
你说在开发阶段,因为 IP 相同无法区分用户?其实我们很少通过 IP 来区分用户,要么是 session,要么是 cookie,node 作为代理层也会把这个头部发送给后端服务器,后端拿到这个头部就能区分用户了。 我觉得这些东西不算难,但是如果不理解的话感觉就很晕乎。 |
8
yhxx 2020-05-12 09:21:59 +08:00
@windychen0 重点不在端口,我的意思是前端资源不应该在服务器上再启动一个 node 服务来提供访问,直接用 nginx 之类的就可以了
|
9
fumichael 2020-05-12 10:12:07 +08:00
浏览器同源策略,跨域了,可以用 nginx 做一下代理转发
|
10
iamppz 2020-05-12 10:12:45 +08:00 1
看描述应该不是 SSR,所以请求是从浏览器出去的,但是因为跨域被拦截了,服务端需要加上允许跨域的配置,例如 SpringBoot:
```java @Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 粗暴一点 config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean; } ``` |
11
iamppz 2020-05-12 10:14:46 +08:00
此外如楼上所说用 Nginx 转发也可以 V 站的 Markdown 到底怎么用啊……
|
12
yiyi11 2020-05-12 13:44:52 +08:00 1
浏览器同源策略,同协议,同域名,同端口。不管 nignx 还是 node (一般选用 nginx ),在本例中,首要作用就是作为一个提供静态资源的服务器,即 html,css,js 。
浏览器请求 nginx,获取静态资源文件。获取到的 js,发送 ajax 请求,根据浏览器同源策略,如果不设置跨域,它只能发回给 nginx (原路返回),然后 nginx 提供另一个关键作用就是作为路由器,转发请求到后端服务,而服务器之间没有同源策略的限制。 |