代码之家  ›  专栏  ›  技术社区  ›  Michael

为什么我只从httpcontext获取url的一部分?

  •  0
  • Michael  · 技术社区  · 6 年前

    我使用代理从远程服务器获取资源。

    下面是代理类:

    public class Proxy : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            string url = context.Request["url"];
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.UserAgent = context.Request.UserAgent;
            request.ContentType = context.Request.ContentType;
            request.Method = context.Request.HttpMethod;
    
            request.ProtocolVersion = HttpVersion.Version11;
            request.KeepAlive = false;
            request.Timeout = 100000;
            request.ReadWriteTimeout = 100000;
            using (var response = request.GetResponse())
            {
                context.Response.ContentType = response.ContentType;
                using (var responseStream = response.GetResponseStream())
                {
                    if (responseStream == null) return;
    
                    responseStream.CopyTo(context.Response.OutputStream);
                    context.Response.OutputStream.Flush();
                }
            }
        }
    }
    

    下面是我对远程服务的ajax调用:

    function wfs(layer) {
    
        let dest_url = "https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS&MAXFEATURES=500&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=ns216630453:WW_MONITOR";
        let proxy_url = "/localhost/Proxy.ashx?url=";
        let url = proxy_url + dest_url;
    
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url); // depricated-'/proxy.ashx?url='+
    
        xhr.onload = function () {
            if (xhr.status === 200) {
                console.log("loader success");
            } else {
                console.log("loader fail");
            }
        },
            xhr.send();
    }
    

    当wfs函数被触发时,proxy类中的processrequest函数被触发,并且 网址 变量为:

    https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS
    

    当我期待 网址 成为:

    https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS&MAXFEATURES=500&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=ns216630453:WW_MONITOR
    

    看来 context.Request["url"] 返回第一个“&”之前的剪切值。

    你知道我为什么 context.request[“url”] 只有一部分 网址 是吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Jacob    6 年前

    您需要对查询参数进行编码,因为它不包含对查询参数安全的字符:

    let url = "/localhost/Proxy.ashx?url=" + encodeURIComponent(dest_url);
    

    为了进一步解释,假设我们是一个url解析器。如果没有编码,您将看到以下字符串:

    /localhost/Proxy.ashx?url=https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS&MAXFEATURES=500&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=ns216630453:WW_MONITOR
    

    解析器在访问字符时将执行以下步骤:

    URL path:              /localhost/Proxy.ashx 
    Query params starting: ?
    Param name:            url
    Starting param value:  =
    (some of these next chars aren't valid, but I'll try my best!)
    Param value:        
       https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS
    Starting next param:   &
    Param name:            MAXFEATURES
    Starting param value:  =
    Param value:           500
    ...etc
    

    因为它遇到了 & 扫描字符串时,它认为参数如下 MAXFEATURES 是代理请求的查询参数, 部分 url 传递给代理请求的参数。因此,当你的代理代码运行时,它只能看到 & 是的。

    对url参数进行编码将提供:

    /localhost/Proxy.ashx?url=https%3A%2F%2Fwww.mysited.com%2Fgeodata2055%2Fservice%2Fmapagent.fcgi%3FSERVICE%3DWFS%26MAXFEATURES%3D500%26VERSION%3D1.0.0%26REQUEST%3DGetFeature%26TYPENAME%3Dns216630453%3AWW_MONITOR
    

    这样,解析器现在只看到 网址 传递给代理处理程序的参数。当代理处理程序现在解析 网址 参数,它将 解码 把原稿还给你 dest_url

    作为一般的经验法则,不要仅仅使用字符串连接来构建url;url不是由字符串组成的,而是由url编码的字符串组成的。