要重现跨域问题,首先得有一个请求的服务端和一个请求端,由于本文不需要其他很复杂的操作,就简单的写一个webapi跟页面就好了,使用iis部署。开发工具vs2017
先创建一个空的WebApi工程
在Models目录下新建一个UserInfo的model,其实就是一个结构类而已,添加几个属性:
public class UserInfo
{
public int Id { get; set; }
public string UserName { get; set; }
public string UserPass { get; set; }
}
然后在Controllers目录下创建一个对应的controller,controller的名称为UserInfoController
鉴于我们这次的目的,里面自动生成的函数我们都可以不要,删掉,重新写一个函数,返回一个userinfo的集合
public IHttpActionResult GetList()
{
//对象集合模拟数据
List<UserInfo> list = new List<UserInfo>()
{
new UserInfo()
{
Id = 1,
UserName = "123",
UserPass = "123"
},
new UserInfo()
{
Id = 2,
UserName = "321",
UserPass = "321"
},
new UserInfo()
{
Id = 3,
UserName = "456",
UserPass = "456"
},
new UserInfo()
{
Id = 4,
UserName = "654",
UserPass = "654"
}
};
return Ok(list);
}
然后修改App_Start目录下的WebApiConfig.cs文件,修改路由规则未api/{controller}/{action}的方式进行访问,同时修改序列化方式让WebAPI默认输出json格式的数据 :
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
}
生成一下项目,然后发布到文件系统,用于部署到iis
至此webapi已具备。
接着我们需要一个请求方,右键刚刚webapi的解决方案,添加一个新的web项目,步骤跟上面差不多,不要勾选Web Api复选框就行了
然后添加一个index.aspx的webform页面,里面放一个输入框,用来输入访问的地址,一个请求按钮,用于发送请求:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="CrossDomainAccessWebAPITest.index" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(function () {
$('#getData').click(function () {
var url = $('#url').val();
$.ajax({
url: url,//'/api/UserInfo/getlist',
dataType: 'json',
success: function (data) {
alert(data);
}
});
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" id="url"/>
<input type="button" value="获取跨域数据" id="getData" />
</div>
</form>
</body>
</html>
用到的jquery自己找一个引进来就好了。
生成一下项目,发布到文件系统,用于iis部署。
至此,请求方与被请求方都具备了,部署起来看看效果是不是我们想要的。
打开iis的管理界面,iis没装的自己网上查一下安装方法就ok了,win+r输入inetmgr回车即可打开iis管理界面 ,
新建两个网站,一个用来部署webapi,一个用来部署发起请求的网站
我这已经建好了,http://192.168.11.226:9530 放的是webapi,http://192.168.11.226:9531放的是请求发起方,把网站启动,浏览
http://192.168.11.226:9531/index.aspx,页面出来了,在输入框内输入 http://192.168.11.226:9530/api/UserInfo/getlist,按F12打开开发者工具,点击页面的 获取跨域数据 按钮,
跨域了,很好,要的就是跨域,不然nginx还上不了场了,首先我们先定义一些角色,本机的ip是192.168.11.226,webapi是被请求方假设叫A,http://192.168.11.226:9530,网站是请求放假设叫B,http://192.168.11.226:9531,现在B请求A的api/UserInfo/getlist产生了跨域。ok,去官网下载最新的nginx包解压,不要放在带中文的目录里解压,好像会有问题,我直接放D盘了,在解压的文件夹里找到conf/ nginx.conf打开编辑,找到server节点
server {
listen 9532;#nginx监听的端口
server_name 192.168.11.226;#当前服务的域名,让nginx监听localhost的9532端口,网站A与网站B的访问都是经过localhost的9532端口进行访问。
#charset koi8-r;
#access_log logs/host.access.log main;
#location / {
# root html;
# index index.html index.htm;
#}
location / {
proxy_pass http://192.168.11.226:9531;
proxy_redirect default;
}
location /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://192.168.11.226:9530;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
#error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root html;
#}
。。。。。。后面的配置不变
配置解释:
1.由配置信息可知,我们让nginx监听192.168.11.226的9532端口,网站A与网站B的访问都是经过192.168.11.226的9532端口进行访问。
2.我们特殊配置了一个“/api”目录的访问,并且对url执行了重写,最后使以“/api”开头的地址都转到“http://192.168.11.226:9532”进行处理。
3.rewrite ^/api/(.*)$ /$1 break;
代表重写拦截进来的请求,并且只能对域名后边以“/api”开头的起作用,例如www.a.com/api/msg?x=1重写。只对/api重写。
rewrite后面的参数是一个简单的正则 ^/api/(.*)$ ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。
break代表匹配一个之后停止匹配。
既然配置了nginx,那么所有的访问都要走nginx,而不是走网站原本的地址(A网站192.168.11.226:9530,B网站192.168.11.226:9531)。所以要修改B网站中的ajax访问地址,把访问地址由
“http://192.168.11.226:9530/api/getlist”改成》》》“/api/api/UserInfo/getlist”
这时候我们浏览器访问的B就不是原来的地址http://192.168.11.226:9531/index.aspx了,而是http://192.168.11.226:9532/index.aspx,同样,输入框里输入的就变成了/api/api/UserInfo/getlist
结果如图
跨域问题解决。