当前位置:首页 » 《关于电脑》 » 正文

Unity WebGL使用nginx作反向代理处理跨域,一些跨域的错误处理(添加了反向代理的配置依旧不能跨域)

13 人参与  2024年10月23日 12:03  分类 : 《关于电脑》  评论

点击全文阅读


反向代理与跨域描述

什么是跨域?

跨域(Cross-Origin Resource Sharing, CORS)是指在浏览器中,当一个网页的脚本试图从一个域名(协议、域名、端口)请求另一个域名的资源时,浏览器会阻止这种请求,除非目标服务器明确允许这种跨域请求。这是为了防止恶意网站通过脚本访问其他网站的资源,从而保护用户的安全。

跨域请求的三个条件

协议不同:例如,httphttps 是不同的协议。域名不同:例如,example.comapi.example.com 是不同的域名。端口不同:例如,example.com:80example.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


点击全文阅读


本文链接:http://zhangshiyu.com/post/176086.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1