为什么我只从 HttpContext 中获取 URL 的一部分?
Why I get only part of the URL from the HttpContext?
我使用代理从远程服务器获取资源。
这是代理 class:
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 函数时,代理 class 中的 ProcessRequest 函数被触发并且 url 变量的值为:
https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS
虽然我希望 url 的值为:
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"]
returns 将值削减到第一个 '&'。
知道为什么我只从 context.Request["url"]
得到 url 的一部分吗?
您需要对查询参数进行编码,因为它不包含对查询参数安全的字符:
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
有了这个,解析器现在只能看到传递给代理处理程序的 url
参数。当代理处理程序现在解析 url
参数时,它会 解码 它,返回你原来的 dest_url
作为一般经验法则,永远不要只使用字符串连接来构建 URLs; URL 不是由字符串组成的,它们是由 URL 编码的字符串组成的。
我使用代理从远程服务器获取资源。
这是代理 class:
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 函数时,代理 class 中的 ProcessRequest 函数被触发并且 url 变量的值为:
https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS
虽然我希望 url 的值为:
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"]
returns 将值削减到第一个 '&'。
知道为什么我只从 context.Request["url"]
得到 url 的一部分吗?
您需要对查询参数进行编码,因为它不包含对查询参数安全的字符:
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
有了这个,解析器现在只能看到传递给代理处理程序的 url
参数。当代理处理程序现在解析 url
参数时,它会 解码 它,返回你原来的 dest_url
作为一般经验法则,永远不要只使用字符串连接来构建 URLs; URL 不是由字符串组成的,它们是由 URL 编码的字符串组成的。