Unity WebGL使用nginx作反向代理处理跨域,一些跨域的错误处理(添加了反向代理的配置依旧不能跨域)
反向代理与跨域描述
什么是跨域?
跨域(Cross-Origin Resource Sharing, CORS)是指在浏览器中,当一个网页的脚本试图从一个域名(协议、域名、端口)请求另一个域名的资源时,浏览器会阻止这种请求,除非目标服务器明确允许这种跨域请求。这是为了防止恶意网站通过脚本访问其他网站的资源,从而保护用户的安全。
跨域请求的三个条件
- 协议不同:例如,
http和https是不同的协议。 - 域名不同:例如,
example.com和api.example.com是不同的域名。 - 端口不同:例如,
example.com:80和example.com:443是不同的端口。
只要这三个条件中有一个不同,就会触发跨域问题。
为什么要用nginx反向代理解决跨域问题?
nginx是exe,不是前端的网页不会受到同源策略的影响,所以可以使用nginx反向代理解决跨域。
前端程序将请求发送给nginx,nginx获取到请求的URL会根据配置文件将请求的URL进行转发,收到数据后再返回给前端。
效果展示

代码描述
在nginx中添加配置文件
location /api/ {proxy_pass http://t.weather.itboy.net;add_header 'Access-Control-Allow-Origin' '*';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';}
服务配置
server {listen 58231;server_name localhost;
nginx会处理对localhost:58231的请求,然后进行匹配,如果是localhost:58231/api/ 的请求则会将请求转发给
http://t.weather.itboy.net ,所以在前端发送的请求的地址应该是nginx的地址, const response = await fetch('http://localhost:58231/api/weather/city/101030100');
在unity的代码中是使用配置文件,需要在StreamingAssets 中创建一个txt,名称是request_url,内容是请求的URL:http://localhost:58231/api/weather/city/101030100 。 然后会发送请求到nginx,nginx根据反向代理配置将请求转发到真正的服务器。
错误处理
已经添加了proxy_pass 配置但是还是提示不能跨域或者404/502
-
proxy_pass后面没有斜杠:- 如果
proxy_pass后面没有斜杠,Nginx 会将匹配的location路径附加到proxy_pass的 URL 后面。 - 举个例子:
当你访问location /api/ {proxy_pass http://t.weather.itboy.net; }http://localhost:58231/api/weather/city/101030100时,Nginx 会将请求转发到http://t.weather.itboy.net/api/weather/city/101030100。
- 如果
-
proxy_pass后面有斜杠:- 如果
proxy_pass后面有斜杠,Nginx 会将匹配的location路径替换为proxy_pass的 URL。 - 举个例子:
当你访问location /api/ {proxy_pass http://t.weather.itboy.net/; }http://localhost:58231/api/weather/city/101030100时,Nginx 会将请求转发到http://t.weather.itboy.net/weather/city/101030100。所以就不可访问就404了。
- 如果
测试网站
一个可以使用get请求获取假数据的网站,网站本身是支持跨域的,所以不配置nginx也可以进行通信。
https://jsonplaceholder.typicode.com/
一个天气预报的API,可以进行get请求的测试
http://t.weather.itboy.net/api/weather/city/101030100
相关代码
Nginx配置
worker_processes 1;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;server {listen 58231;server_name localhost;location / {root html;index index.html index.htm;}location /api/ {# 将http://t.weather.itboy.net 替换为实际的服务器proxy_pass http://t.weather.itboy.net;add_header 'Access-Control-Allow-Origin' '*';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';}# On-disk Brotli-precompressed data files should be served with compression enabled:location ~ .+\.(data|symbols\.json)\.br$ {gzip off;add_header Content-Encoding br;default_type application/octet-stream;}# On-disk Brotli-precompressed JavaScript code files:location ~ .+\.js\.br$ {gzip off;add_header Content-Encoding br;default_type application/javascript;}# On-disk Brotli-precompressed WebAssembly files:location ~ .+\.wasm\.br$ {gzip off;add_header Content-Encoding br;default_type application/wasm;}# On-disk gzip-precompressed data files should be served with compression enabled:location ~ .+\.(data|symbols\.json)\.gz$ {gzip off;add_header Content-Encoding gzip;default_type application/octet-stream;}# On-disk gzip-precompressed JavaScript code files:location ~ .+\.js\.gz$ {gzip off;add_header Content-Encoding gzip;default_type application/javascript;}# On-disk gzip-precompressed WebAssembly files:location ~ .+\.wasm\.gz$ {gzip off;add_header Content-Encoding gzip;default_type application/wasm;}error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}
}
Unity代码
using Best.HTTP;
using Cysharp.Threading.Tasks;
using System;
using UnityEngine;
using UnityEngine.Networking;public class SendGetR : MonoBehaviour
{private string requestUrlFilePath = Application.streamingAssetsPath + "/request_url.txt";async void Start(){Debug.Log("开始发送请求啦!");string fileContent = await ReadFileAsync(requestUrlFilePath);await GetObtainCodingRulesAsync(fileContent);}/// <summary>/// 异步读取文件内容/// </summary>/// <param name="filePath">文件路径</param>/// <returns>文件内容</returns>public async UniTask<string> ReadFileAsync(string _filePath){try{using (UnityWebRequest uwr = UnityWebRequest.Get(_filePath)){await uwr.SendWebRequest();Debug.Log("请求到的URL是:" + uwr.downloadHandler.text);return uwr.downloadHandler.text;}}catch (System.Exception e){Debug.LogError("读取文件失败: " + e.Message);return null;}}/// <summary>/// 异步获取赋码规则/// </summary>/// <param name="url">请求的URL</param>/// <returns>赋码规则列表</returns>public async UniTask<string> GetObtainCodingRulesAsync(string _url){try{var request = new HTTPRequest(new System.Uri(_url), HTTPMethods.Get, (req, res) =>{if (res.IsSuccess){Debug.Log("返回的数据是:" + res.DataAsText);}else{Debug.Log("发送失败tmp_requestURL: " + _url);}});await request.Send();await UniTask.WaitUntil(() => request.Response.DataAsText != null);return request.Response.DataAsText;}catch (Exception e){Debug.LogError($"发送失败: {e.Message}");}return "没有获取到数据";}
}
测试使用html代码
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>发送GET请求</title>
</head><body><h1>发送GET请求到CSDN</h1><p>请点击按钮发送请求,并在浏览器控制台查看结果。</p><!-- 添加一个按钮 --><button id="sendRequestButton">发送请求</button><script>// 发送GET请求的函数async function sendGetRequest() {try {// 发送GET请求到你的Nginx服务器const response = await fetch('http://localhost:58231/api/weather/city/101030100');// 检查响应状态if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}// 读取响应内容const data = await response.text();// 在控制台中显示响应内容console.log('Response status:', response.status);console.log('Response data:', data);} catch (error) {// 捕获并显示错误console.error('Error:', error);}}// 获取按钮元素const button = document.getElementById('sendRequestButton');// 为按钮添加点击事件监听器button.addEventListener('click', sendGetRequest);</script>
</body></html>
Enjoy Life
相关文章:
Unity WebGL使用nginx作反向代理处理跨域,一些跨域的错误处理(添加了反向代理的配置依旧不能跨域)
反向代理与跨域描述 什么是跨域? 跨域(Cross-Origin Resource Sharing, CORS)是指在浏览器中,当一个网页的脚本试图从一个域名(协议、域名、端口)请求另一个域名的资源时,浏览器会阻止这种请求…...
视频转文字免费的软件有哪些?6款工具一键把视频转成文字!又快又方便!
视频转文字免费的软件有哪些?在视频制作剪辑过程中,我们经常进行视频语音识别成字幕,帮助我们更好地呈现视频内容的观看和宣传,市场上有许多免费的视频转文字软件,可以快速导入视频,进行视频内音频的文字转…...
解决DHCP服务异常导致设备无法获取IP地址的方法
DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数,可以简化网络配置过程。但是,如果DHCP服务出现异常时,设备可能无法正常获取IP地址,会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…...
Python机器学习模型的部署与维护:版本管理、监控与更新策略
🚀 Python机器学习模型的部署与维护:版本管理、监控与更新策略 目录 💼 模型版本管理 使用DVC进行数据和模型的版本控制,确保可复现性 🔍 监控与评估 部署后的模型性能监控,使用Prometheus和Grafana进行实…...
免费送源码:Java+ssm+JSP+Ajax+MySQL SSM汽车租赁管理系统 计算机毕业设计原创定制
摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对汽车租赁信息管理等问题,对其进…...
Vivado viterbi decoder license
Viterbi Decoder 打卡以上链接 添加后next后, 会发送lic文件到邮件,vivado导入lic即可...
【FastAdmin】PHP的Trait机制:代码复用的新选择
PHP的Trait机制:代码复用的新选择 大家好,我是田辛老师。最近收到很多同学的私信,询问关于PHP中Trait机制的相关问题。今天,我们就来详细探讨一下这个强大的代码复用工具,以及它在ThinkPHP 5(简称Tp5&…...
小红书制作视频如何去原视频音乐,视频如何去原声保留背景音乐?
在视频编辑、音乐制作或个人娱乐中,有时我们希望去掉视频中的原声(如对话、解说等),仅保留背景音乐。这种处理能让观众更加聚焦于视频的氛围或节奏,同时也为创作者提供了更多创意空间。选择恰当的背景音乐,…...
netty之Netty使用Protobuf传输数据
前言 在netty数据传输过程中可以有很多选择,比如;字符串、json、xml、java对象,但为了保证传输的数据具备;良好的通用性、方便的操作性和传输的高性能,我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支…...
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
四题都比较简单,可以直接秒。 1. 力扣2082:富有客户的数量 1.1 题目: 表: Store ------------------- | Column Name | Type | ------------------- | bill_id | int | | customer_id | int | | amount | int | -------------…...
快速了解Java中的15把锁!
目录 了解 总览 乐观锁 悲观锁 互斥锁和同步锁 公平锁 非公平锁 自旋锁 可重入锁(递归锁) ReadWriteLock读写锁 共享锁 独占锁 偏向锁 轻量级锁 重量级锁 锁优化 在 Java 中,锁是一种用于实现多线程之间同步和互斥的机制。 了…...
TypeScript 封装 Axios 1.7.7
随着Axios版本的不同,类型也在改变,以后怎么写类型? yarn add axios1. 封装Axios 将Axios封装成一个类,同时重新封装request方法 重新封装request有几个好处: 所有的请求将从我们定义的requet请求中发送ÿ…...
【数据结构】【链表代码】移除链表元素
移除链表元素 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val) { // 创建一个虚拟头节点,以处理头节点可能被删除的情况 struct…...
作文-杭州游记
杭州的学习与游历 在这个风景如画的城市——杭州,学习信息学的日子如同西湖的水,清澈而又深邃。在这里,课堂与自然的交融、技术与文化的碰撞,构成了一幅独特的画卷。 学习之旅 信息学的课程不仅仅是对代码和算法的解析࿰…...
降压芯片TPS54821
降压芯片TPS54821 介绍 价格低廉,只需1.5元。是一个同步整流降压BUCK电路。MOS管内置。输入电压为4.5V至17V,输出电压为0.6V到15V,输出电流最大到8A。是QFN封装,焊接时有些许困难。得益于QFN封装,其引线电感非常的小…...
YOLO v1详解解读
🚀 在此之前主要介绍了YOLO v5源码的安装和使用(YOLO v5安装教程),接下来将探索YOLO的实现原理,作为一个金典的单阶段目标检测算法,应该深度的理解它的构建思想;所以本系列文章将从LOVO v1出发到…...
【动态规划-最长公共子序列(LCS)】【hard】【科大讯飞笔试最后一题】力扣115. 不同的子序列
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 10^9 7 取模。 示例 1: 输入:s “rabbbit”, t “rabbit” 输出:3 解释: 如下所示, 有 3 种可以从 s 中得到 “rabbit”…...
深入理解 JavaScript 中的 void`运算符和 yield*表达式
深入理解 JavaScript 中的 void 运算符和 yield* 表达式 在 JavaScript 中,void 运算符和 yield* 表达式是两个功能独特但常被忽视的运算符。本文将详细介绍它们的用法和应用场景,帮助您更好地理解和运用这两个运算符。 目录 void 运算符概述void 运算…...
第四节——从深层剖析指针(让你不再害怕指针)
文章目录 1. 字符指针变量剑指offer例题 2. 数组指针变量2.1 数组指针变量是什么?2.2 数组指针变量怎么初始化 3. ⼆维数组传参的本质代码实现 4. 函数指针变量4.1 函数指针变量的创建4.3 两段有趣的代码4.3.1 typedef 关键字 5. 函数指针数组的定义 1. 字符指针变量…...
openpnp - 吸嘴校正失败的opencv参数分析
文章目录 openpnp - 吸嘴校正失败的opencv参数分析概述笔记阶段验证 - N2吸嘴校验完NT1NT2 阶段验证 - 底部相机高级校验完NT1NT2 参数比对保存 “阶段验证 - N2吸嘴校验完” 的NT1/NT2图像重建参数检测环境NT1ok的3个参数值NT1err的3个参数值NT2ok的3个参数值NT2err的3个参数值…...
ai辅助开发c语言:如何利用快马智能编程助手精通数据结构与算法
今天想和大家分享一个特别实用的学习经验——如何用AI辅助工具高效学习C语言的数据结构与算法。作为一个刚接触数据结构的小白,我在实现单链表时遇到了不少坑,但通过InsCode(快马)平台的AI编程助手,整个过程变得轻松多了。 链表创建与节点插入…...
Pixel Epic效果可视化:研报生成后自动进行事实核查与数据溯源标注演示
Pixel Epic效果可视化:研报生成后自动进行事实核查与数据溯源标注演示 1. 引言:当研报写作遇上像素冒险 在金融分析和行业研究领域,撰写高质量研究报告一直是个耗时费力的过程。传统方式下,分析师需要花费大量时间收集数据、验证…...
嵌入式开发调试宏与性能优化实战
1. 嵌入式开发调试宏的妙用在嵌入式开发中,调试是最耗时耗力的环节之一。每次修改代码后都需要重新烧录、运行、观察结果,这个过程往往要重复数十次。而合理使用编译器提供的调试宏,可以大幅提升调试效率。1.1 基础调试宏解析GCC编译器提供了…...
human-pose-estimation.pytorch:简单而强大的人体姿态估计终极指南
human-pose-estimation.pytorch:简单而强大的人体姿态估计终极指南 【免费下载链接】human-pose-estimation.pytorch The project is an official implement of our ECCV2018 paper "Simple Baselines for Human Pose Estimation and Tracking(https://arxiv.o…...
【ACCELERATED GSTREAMER PERFORMANCE GUIDE】Choosing Between videoconvert and nvvidconv for Optimal Vid
1. 理解videoconvert与nvvidconv的核心差异 第一次接触GStreamer视频处理时,很多人都会困惑到底该用videoconvert还是nvvidconv。这个问题就像选择交通工具:你是要经济实惠的公交车(CPU处理),还是要速度更快的出租车&a…...
Cursor Pro功能持续访问解决方案:系统化AI编程助手权限管理方法论
Cursor Pro功能持续访问解决方案:系统化AI编程助手权限管理方法论 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reach…...
DeepSeek-Coder-V2-Lite-Instruct社区成功案例:开发者如何用AI助手实现项目突破
DeepSeek-Coder-V2-Lite-Instruct社区成功案例:开发者如何用AI助手实现项目突破 【免费下载链接】DeepSeek-Coder-V2-Lite-Instruct 开源代码智能利器——DeepSeek-Coder-V2,性能比肩GPT4-Turbo,全面支持338种编程语言,128K超长上…...
AQS深度探索:以ReentrantLock看Java并发编程的高效实现
在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…...
NVIDIA Profile Inspector实战手册:从参数调试到显卡性能全面优化
NVIDIA Profile Inspector实战手册:从参数调试到显卡性能全面优化 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 在PC硬件优化领域,专业工具与普通用户之间往往存在技术鸿沟。N…...
二、空间碎片聚类-轨道计算与J2000坐标系实现
1. 整体思路 在空间碎片监测、卫星对地观测等任务中,需要精确知道卫星和空间目标在某一时刻的位置。通常我们使用开普勒轨道六要素(半长轴、偏心率、倾角、升交点赤经、近地点幅角、真近点角)来描述轨道,并通过轨道动力学外推得到任意时刻的位置。本文实现了一套基于J2000…...
