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个参数值…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
