简短的回答是你不这样做。
虽然理论上可行,但这比仅仅解决 CORS 问题和为 Web API 使用单独的服务器要求更高,但用处更少。仅当您知道如何在客户端和服务器上处理 CORS 并且您知道不会想到问这个问题时,这一点才很明显。
为了帮助这条路标昏暗的道路上迷路的人,这里是如何使用 9000 上的 Aurelia 客户端处理 IIS7 MVC/WepApi2 的 CORS。
服务器
将其作为 <system.webServer> 部分的子项放入 Web API 项目根目录下的 web.config 文件中。
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
对于这个例子,http://testserver/DAL3/api/Form 有一个 Web API 服务,其方法绑定到 post。
这是一个支持类
public class JsonRequest
{
public int UID { get; set; }
public string Command { get; set; }
public string Raw { get; set; }
}
这就是 Web 服务的样子。有一个支持它的 LINQ2SQL 模型,为简洁起见,我将其省略。
using Newtonsoft.Json;
using System.Linq;
using System.Reflection;
using System.Web.Http;
namespace DAL3.Controllers
{
public class FormController : ApiController
{
// POST: api/Form
public object Post([FromBody]JsonRequest jsr)
{
var T = GetType();
var M = T.GetMethod(jsr.Command, BindingFlags.NonPublic | BindingFlags.Instance);
var parms = new object[] { jsr.UID, jsr.Raw };
if (M == null) return string.Format("M is null (\"{0}\")",jsr.Command);
if (parms == null) return "parms is null";
return M.Invoke(this, parms);
}
object Get(int UID, string Raw)
{
var dc = new Models.FormsDataContext();
if (string.IsNullOrEmpty(Raw))
{
return dc.Forms.Where(x => x.FormEngine == true);
}
else
{
var id = JsonConvert.DeserializeObject<GetParams>(Raw).Id;
return dc.Forms.Where(x => x.FormID == id);
}
}
}
//this class describes how to parse the parameters for Get
class GetParams
{
public int Id { get; set; }
}
//if you defined some other method Quux that takes parameters
//create a QuuxParams class that matches what JS sends
}
所有这些反射业务都允许您在Command 中指定一个方法名称,并在Raw 中传递您喜欢的任何内容。 UID 是用户标识符。
这样做可以让您将 CORS 合规性与您的请求分开,并自动对您在 Raw 中输入的任何内容进行编码。可能应该命名为Parameters,但无论如何。现在您知道如何将它们组合在一起了。
客户
使用 bash 并将 pwd 设置为应用的根目录:
npm i aurelia-http-client --save
然后将其添加到 aurelia.json 中的供应商捆绑包依赖项中。您不需要对象,只需要双引号中的名称和尾随逗号,以适用于有效的 JSON 语法。
在您的代码中,您需要导入它。
import {HttpClient} from 'aurelia-http-client';
这是一个发布到名为 Form 的 Web API 服务的示例,该服务位于名为 testserver 的盒子上名为 DAL3 的网络应用程序中。
let foo = {
UID: 18974,
Command: "Get",
Raw: null
}
let content = "UID=" + foo.UID + "&Command=" + foo.Command + "&Raw=" + JSON.stringify(foo.Raw)
let client = new HttpClient();
let req = client.createRequest("http://testserver/DAL3/api/Form")
.asPost()
.withHeader("Content-Type","application/x-www-form-urlencoded")
.withContent(content)
.send()
.then(res => {
console.log("Hurrah we have a response!");
});
注意事项
以下任何一项都将导致使用动词 OPTIONS 的“预检”请求,这将导致失败。
- 添加非标准标题
- 使用除
text/plain 或application/x-www-form-urlencoded 以外的内容类型
- 使用 GET 或 POST 以外的动词
编码内容
对象foo 根的三个属性是URL 编码的,并用& 符号分隔,如上面的示例代码所示。 Raw 可以包含一个对象,甚至是一个对象的有向无环图。 JSON.stringify 正确处理两者。 Null 将解析为一个空字符串,但 URL 编码的解码将产生一个 null,所以这很好;重要的是 Raw 参数应该存在以满足另一端的 Web API 签名匹配。