大龄小白请教:跨域问题

133 天前
 xiao20161010

环境: 1-用 jQuery 的小案例做了一个 post 请求 2-用 eclipse 搭建了一个简单的 Tomcat+servlet ,并运行起来,输入 IP 或者 localhost 都可以正常访问 3-本地直接打开 html 文件,用 jQuery 的 post 请求传两个参数 username 和 password ,URL 地址就是 IP:8080/项目名

报 cors 错误,应该是跨域的问题,本地直接打开的协议和请求的协议不一样,这是从元宝提问所给的回答中得到的消息,但是我死活解决不了,后台设置什么 header 之类的,前台设置 manifest 之类的,都不好使

无解了吗,小白请教

这个问题简单描述就是我本地写的是静态 HTML ,但是需要请求局域网内的服务器来获取数据

3273 次点击
所在节点    程序员
29 条回复
xiao20161010
133 天前
servlet 访问没问题,能接收也能返回,但是接收的都是 null 值,我也尝试了将本地文件放到项目下运行,是可以的,但是我需要解决跨域问题,postman 吗
Arrowing
133 天前
一般就是在你的服务设置跨域响应头,如:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
参考文档:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Guides/CORS
SDYY
133 天前
Mandelo
133 天前
npx
zkkang
133 天前
2 楼已经给了解决方案。
简单点理解,浏览器安全策略不允许网页 uri 的域名和 api 请求域名不一致。需要在 api 返回的 header 头里面标记,网页 uri 的域名有权限请求 api 信息。
详细的介绍看下面这个帖子:
https://dzone.com/articles/do-you-really-know-cors
Ayanokouji
133 天前
ajax 还要设置:Access-Control-Allow-Credentials: true

js 端:
使用 fetch() 时,通过将 Request() 构造函数中的 credentials 选项设置为 "include"。
使用 XMLHttpRequest 时,通过将 XMLHttpRequest.withCredentials 属性设置为 true 。

参考: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Reference/Headers/Access-Control-Allow-Credentials
restkhz
133 天前
我不确定,但是我问一嘴:
你是不是浏览器直接打开了本地文件?我是说,你没有通过一个 http 服务器,本地通过 file://协议打开的?

如果是这样的话你怎么设置都没用的。
newaccount
133 天前
搭个 nginx 转一下,别折腾跨域,没必要这么麻烦
yiwayhb
133 天前
@newaccount 正解
qingbaihe
133 天前
把静态文件放到 Tomcat 里面
p8YFk4f3E8SJ3aEv
133 天前
本地启用一个 nginx 代理
bbao
133 天前
楼主这是入了哪个培训机构的天坑~~~~~~~~~~~~~~

学费多少?
AV1
133 天前
你应该把 html 文件也部署到服务器上,不要在本地 file://下打开 html 文件。
canvascat
133 天前
或者用 vite 启动项目,配置一下代理服务
importmeta
133 天前
在后端框架配置一下 cors 功能, 就可以解决跨域, 把浏览器打开前端页面的那个地址和端口 加到 cors 上面, 真实线上环境就改成网址.

OP 提到了 jQuery,eclipse,Tomcat,servlet, 感觉都是很老的技术栈了.
如果不考虑 SEO, 建议使用 Vite Webpack 这样的工具构建项目加任何一个前端框架.
如果考虑 SEO, 用 Next, Nuxt, Astro 的 SSR SSG 功能.
这些框架有丰富的生态并且自带前端反向代理,可以解决跨域.



用最原始的 HTML 多页面加页内 JavaScript 也可以, 这种就是开发慢一点而已.
0x663
133 天前
@Arrowing CORS 信任任意来源漏洞
你就设吧一设一个不吱声
y3322
133 天前
直接把浏览器的同源策略关闭掉, --disable-web-security 不用关心什么请求头
sentinelK
133 天前
楼主的描述相当的详尽,部分楼上是一个字都不带看的。

1 、楼主是本地 html 文件直接打开。
2 、楼主要 ajax 的请求 url 一个非本域的地址(也就是不在当前目录内)。

我的答案是不能这样做。

首先楼主要先定义你这么做(把 html 放在文件夹中运行)是想实现什么效果?
如果只是测试 Servlet 的 API 是否正常运行,那么有 postman 等工具。
如果是想简单的测试网页>ajax>服务器端 API 的整个动态网页链路,那么需要你把网页放在一个 web 容器中执行(可以是传统的 web 容器比如 tomcat 、IIS ,也可以通过 nodeJS 环境下的脚手架来运行,比如 webpack 、vite 等)。

通过 file://协议打开网页,从你学习的认知维度上,与真正的 web 开发是有很大差异的。一定要用 http 、https 协议来实现。


然后是关于跨域。
如果你是以贴近实战的目的,就不要去纠结“绕过跨域验证”。而是要考虑“怎么不跨域”。换句话说,禁止跨域,是浏览器的一种安全机制。任何教你在浏览器侧实现跨域的,都是拿信息安全玩火。

业内最通用的解决方法:反向代理。
既通过服务器端的二次转发,来解决跨域问题。页面请求的都是本域内的 URL 。这个 URL 本身并不存在真正的 Servlet 服务。
然后通过一些软件(比如最知名的 nginx ,业内一般叫“中间件”,也可以在 Web 容器中直接设置策略转发。),把合法且正确的请求转发到真正的 API URL 中。

这种在服务器端,把请求转发到真正的业务 api 路径的服务,叫反向代理。
pkoukk
133 天前
通过设置浏览器头绕过跨域并不是解决问题的方法,只是开发环境下为了方便的产物
如果你是真的想知道并学习这个问题的解决方案,只有反向代理一条路
sentinelK
133 天前
然后就是 CORS ( Cross-Origin Resource Sharing ),也就是通过 web 容器的响应头设置,可以通知浏览器当前网站允许请求哪些域名,使用哪些请求方法。

再往后就是一些歪招了,好奇楼主可以自己查。
关键字:JSONP (利用浏览器对 script 引用没有跨域限制,把请求承载伪装成 script 引用)、WebSocket (本意是实现浏览器与服务器的长连接)、iframe 给主页面 postMessage 等方式。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1133062

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX