V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xiao20161010
V2EX  ›  程序员

大龄小白请教:跨域问题

  •  
  •   xiao20161010 · 16 天前 via Android · 2724 次点击

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

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

    无解了吗,小白请教

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

    29 条回复    2025-05-21 09:21:52 +08:00
    xiao20161010
        1
    xiao20161010  
    OP
       16 天前 via Android
    servlet 访问没问题,能接收也能返回,但是接收的都是 null 值,我也尝试了将本地文件放到项目下运行,是可以的,但是我需要解决跨域问题,postman 吗
    Arrowing
        2
    Arrowing  
       16 天前
    一般就是在你的服务设置跨域响应头,如:
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: *
    参考文档:
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Guides/CORS
    SDYY
        3
    SDYY  
       16 天前
    Mandelo
        4
    Mandelo  
       16 天前
    npx
    zkkang
        5
    zkkang  
       16 天前
    2 楼已经给了解决方案。
    简单点理解,浏览器安全策略不允许网页 uri 的域名和 api 请求域名不一致。需要在 api 返回的 header 头里面标记,网页 uri 的域名有权限请求 api 信息。
    详细的介绍看下面这个帖子:
    https://dzone.com/articles/do-you-really-know-cors
    Ayanokouji
        6
    Ayanokouji  
       16 天前
    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
        7
    restkhz  
       16 天前   ❤️ 2
    我不确定,但是我问一嘴:
    你是不是浏览器直接打开了本地文件?我是说,你没有通过一个 http 服务器,本地通过 file://协议打开的?

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

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

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



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

    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
        19
    pkoukk  
       16 天前
    通过设置浏览器头绕过跨域并不是解决问题的方法,只是开发环境下为了方便的产物
    如果你是真的想知道并学习这个问题的解决方案,只有反向代理一条路
    sentinelK
        20
    sentinelK  
       16 天前
    然后就是 CORS ( Cross-Origin Resource Sharing ),也就是通过 web 容器的响应头设置,可以通知浏览器当前网站允许请求哪些域名,使用哪些请求方法。

    再往后就是一些歪招了,好奇楼主可以自己查。
    关键字:JSONP (利用浏览器对 script 引用没有跨域限制,把请求承载伪装成 script 引用)、WebSocket (本意是实现浏览器与服务器的长连接)、iframe 给主页面 postMessage 等方式。
    henix
        21
    henix  
       16 天前
    如果你要从 file:// 的地址访问 http:// 的 API ,那各个浏览器默认都是不支持的
    参考: https://stackoverflow.com/questions/10752055/cross-origin-requests-are-only-supported-for-http-error-when-loading-a-local
    所以推荐的做法是把 html 放到 tomcat 里面,然后统一通过 http:// 协议访问,这样就不存在跨域问题
    但看你的描述似乎不能这样,为什么必须要本地打开 html ?你想实现什么功能?
    danhahaha
        22
    danhahaha  
       16 天前
    我觉得楼主可能是收拾房子翻出一本《 7 天精通网站建设》,要不然 jquery 这几个字母很难看到了,这大概是今年第二次见到这个词,上一次还是提交某政府网站的资料无法提交时候点开开发工具的时候
    oneisall8955
        23
    oneisall8955  
       16 天前
    日经贴,上周才看到跨域贴
    restkhz
        24
    restkhz  
       16 天前
    额,更正一下,我做了一下测试。搭建了一个 api 服务,走 json ,而后用 jquery 提交 json ,本地 html 直接浏览器打开。
    用的 chrome 两个版本,125 和 86 ,还有一个 firefox 。总共三个浏览器。
    只要设置了 Access-Control-Allow-Origin: * 其实是可以跨站的。我不清楚无论是 Tomcat+servlet ,也不知道你提交的是不是 json 。反正,json post 走了 preflight 还是普通 get 和 post 都成功了。可能 java 那边设置不同吧,我不懂。

    但是我记得之前貌似是不可以的...

    当然我也不得不吐槽一下这些浏览器安全设计...SOP 太严格,就搞 cors 打补丁,搞搞 cookie 策略,搞搞 CSP...
    xiaoming1992
        25
    xiaoming1992  
       16 天前
    别搞什么 nginx, 繁琐得要死。如果要起服务,直接在 htm 文件所在的目录 `python3 -m http.server 8000` 或者 `npx http-server . -p 8000`起一个服务就好了。
    xiaoming1992
        26
    xiaoming1992  
       16 天前
    跨域还有可能是你带了响应没有明确允许的 header
    pytth
        27
    pytth  
       16 天前 via Android
    实在不行 jsonp
    lyxxxh2
        28
    lyxxxh2  
       16 天前
    我猜 ai 让你改*
    *在 chrome 不管用的,而在搜狗浏览器又可以。
    指定 origin 。
    origin method head 都有可能是问题,最好发控制台的红色报错。
    lyxxxh2
        29
    lyxxxh2  
       16 天前
    @lyxxxh2

    记错了,反正能不用*就不用。
    本想偷懒,结果没偷到。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3758 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 05:12 · PVG 13:12 · LAX 22:12 · JFK 01:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.