动静分离跨域自定义请求头部信息

本文详细介绍了如何在ASP.NET MVC4 WebAPI项目中配置跨域请求,并通过自定义Header进行请求验证。内容涵盖Web.config配置、过滤器代码实现、客户端JQuery调用示例等,为开发者提供全面的跨域解决方案。

环境:Asp.net mvc 4 wepapi ,JQuery 1.9.1

1.webapi中Web.config配置项
自定义header项:customHeaderName
<httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET" />
        <add name="Access-Control-Allow-Headers" value="x-requested-with,content-type,customHeaderName" />
        <add name="Access-Control-Allow-Origin" value="*" />   --可使用固定的域名     
      </customHeaders>


2.WEBAPI端过滤器代码并在WebApiConfig中注册config.Filters.Add(new ValidationCustomHeaderFilter());
public class ValidationCustomHeaderFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {

            if (actionContext.ActionDescriptor.ActionName == "Login" || actionContext.ActionDescriptor.ActionName == "Logout")
            {
                base.OnActionExecuting(actionContext);
                return;
            }
            var request = actionContext.Request;
            if (request.Method == HttpMethod.Options)
            {
                base.OnActionExecuting(actionContext);
                return;
            }
            
            string customHeaderName = string.Empty;
            

            if (request.Headers.Contains("CustomHeaderName"))
            {
                customHeaderName = HttpUtility.UrlDecode(request.Headers.GetValues("customHeaderName").FirstOrDefault());
            }
            
            if (string.IsNullOrEmpty(customHeaderName))
            {                
                actionContext.Response = new HttpResponseMessage { Content = new StringContent("自定义Header不能为空") };
                return;
            }
            try
            {
                bool validateFlag = ValidationData(customHeaderName);
                if (validateFlag)
                {                    
                    actionContext.Response = new HttpResponseMessage { Content = new StringContent("验证失败") };
                    return;
                }
            }
            catch (Exception ex)
            {
                actionContext.Response = new HttpResponseMessage { Content = new StringContent("验证异常:"+ex.Message) };
                return;
            }

            base.OnActionExecuting(actionContext);
        }

        private bool ValidationData(string customHeaderName)
        {
            throw new NotImplementedException();
        }

    }
3.Action需要添加[HttpOptions]

也可以在Global中加上事件

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            var curContext = HttpContext.Current;
            if (curContext.Request.HttpMethod == "OPTIONS")
            {
                curContext.Response.End();
            }
        }
4.客户端代码
$(function () {
            
            //全局设置,
    //注意:中文需要使用encodeURI否则不生效
            $.ajaxSetup({
                //方案一
                //headers: { "CustomHeaderName": encodeURI(CustomHeaderName)}
                //方案二
                beforeSend: function (xhr, settings) {
                    xhr.setRequestHeader("CustomHeaderName", encodeURI(customHeaderValue));
                }
            })

            $.ajax({

                type: "get",
                url: 'http://localhost:21774/Values/Get?Id=888',
                dataType: 'json',
                //单个方法中
                //方案一
                //headers: { "CustomHeaderName": encodeURI(CustomHeaderName)},
                //方案二
                //beforeSend: function (xhr, settings) {                    
                //    xhr.setRequestHeader("CustomHeaderName", encodeURI(customHeaderValue));
                //},        
                success: function (data) {
                    if (data.IsSuccess) {
                        alert("data success");
                    } else {
                        alert("data error");
                    }
                },
                error: function (err) {
                    alert(err.statusText);
                }
            })
        })

### 解决方案概述 当处理带有自定义请求头的资源共享 (CORS) 请求时,服务器端需正确配置 `Access-Control-Allow-Headers` 响应头来允许这些额外的头部信息[^1]。对于 Spring Boot 应用程序,在控制器方法中通过设置响应头可实现这一点[^2]。 具体来说,为了使浏览器接受并传递特定于应用逻辑的自定义请求头(例如 `roleId`, `username`, 或者 `identity`),必须显式声明它们作为被许可使用的 HTTP 头部之一[^3][^4]。这可以通过修改 Web 服务中的 CORS 配置完成,确保所有必要的自定义字段都被列入白名单内。 针对 Flask 框架下的 Python web 应用,则可通过调整 @cross_origin() 装饰器内的参数选项达成相同效果;特别是利用 `allow_headers` 参数指定哪些客户端发起的请求携带的附加头部应该得到认可[^5]。 ### 实现示例 #### Nginx 中间件配置 ```nginx server { location /api/ { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization, roleId, username, identity'; } } ``` 此段 NGINX 设置展示了如何扩展默认允许的请求头集合以包含应用程序特有的条目,比如 `roleId`, `username`, 及 `identity`. #### Java/SpringBoot 后端代码片段 ```java import org.springframework.web.bind.annotation.CrossOrigin; import javax.servlet.http.HttpServletResponse; @CrossOrigin(origins = "*", allowedHeaders = {"*", "Authorization", "roleId", "username", "identity"}) @RestController public class MyController { @GetMapping("/example") public ResponseEntity<String> example(HttpServletResponse response){ String codeId = "customValue"; response.setHeader("codeId", codeId); response.addHeader("Access-Control-Expose-Headers", "*"); return new ResponseEntity<>("Success", HttpStatus.OK); } } ``` 上述 Java 类型展示了一个 RESTful API 控制器的例子,它不仅开放了标准的 CORS 政策还特别指定了几个重要的自定义请求头项供前端调用时使用. #### Flask-Python 示例 ```python from flask import Flask, jsonify from flask_cors import cross_origin app = Flask(__name__) @app.route('/data') @cross_origin(allow_headers=['Content-Type', 'Authorization', 'roleId', 'username', 'identity']) def get_data(): return jsonify({"message": "Data fetched successfully!"}) ``` 这段Python脚本说明了怎样借助Flask框架及其插件flask-cors轻松地向API接口添加细粒度控制的支持,从而安全有效地管理来自不同源的数据交换过程.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值