一个Option请求引发的深度解析

遇到Option请求的问题,查到一篇好文章,转载一下。

在当前项目中,前端通过POST方式访问后端的REST接口时,发现两条请求记录,一条请求的Request Method为Options,另一条请求的Reuest Method为Post。想要解决这个疑惑还得从以下3个概念说起。

Http Options Method

RFC2616标准(现行的HTTP/1.1)中如下描述:

简而言之,OPTIONS请求方法的主要用途有两个:

1、获取服务器支持的HTTP请求方法;

2、用来检查服务器的性能。

 

CORS(跨域资源共享)

CORS是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 

使用CORS的方式非常简单,但是需要同时对前端和服务器端做相应处理。

1、  前端

客户端使用XmlHttpRequest发起Ajax请求,当前绝大部分浏览器已经支持CORS方式,且主流浏览器均提供了对跨域资源共享的支持。

2、  服务器端

如果服务器端未做任何配置,则前端发起Ajax请求后,会得到CORS Access Deny,即跨域访问被拒绝。

对于C#做如下配置可允许资源的跨域访问: 

<system.webServer>
...
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type" />
<add name="Access-Control-Allow-Methods" value="PUT,GET,POST,DELETE,OPTIONS"/>
</customHeaders>
</httpProtocol>
</system.webServer>

对于nodejs做如下配置可允许资源的跨域访问: 

//设置CORS跨域访问
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, accept, origin, content-type");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});

Access-Control-Allow-Origin:*表示允许任何域发起请求,如果只允许特定的域访问,则设置Access-Control-Allow-Origin:xxx为具体域名即可。

 

Preflighted Requests(预检请求)

Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。

下面的2种情况需要进行预检:

1、  简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求;

2、中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等。

 

了解完这3个概念,其实答案已经了然了。

 

参考:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

http://blog.youkuaiyun.com/hfahe/article/details/7730944

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

<think>好的,我现在需要分析用户提供的关于CMake在大型项目中的使用指南。首先,用户之前已经得到了一个结构化的回答,现在他们要求“分析上述文件”,也就是对之前的回答进行深入解读。我需要理解用户的需求是什么,他们可能希望了解这份指南的结构、内容重点,或者需要进一步的解释和补充。 首先,我应该回顾用户提供的原始回答。这个回答分为七个主要部分:核心优势、项目结构设计、依赖管理进阶、编译加速策略、安装与打包、测试与CI集成以及典型问题解决方案。每个部分都有详细的子项和代码示例。用户现在的请求是分析这个文件,可能希望得到总结、关键点提取,或者对某些部分进行更详细的解释。 接下来,我需要考虑用户可能的身份和使用场景。用户可能是在学习CMake,特别是如何管理大型项目。他们可能是一位开发者,正在尝试优化现有的构建系统,或者开始一个需要平台支持的大型项目。因此,分析需要突出这份指南的实用性和最佳实践,帮助用户理解如何应用这些策略。 我需要确定分析的结构。可能需要按照原始回答的各个部分进行逐一分析,指出每个部分的重要性和实际应用。例如,核心优势部分强调了CMake的平台能力和依赖管理,这对于大型项目至关重要。项目结构设计部分提供了目录布局建议,这对于维护代码的可维护性非常重要。依赖管理部分提到了第三方库的集成方法,这对于减少依赖问题很有帮助。 同时,我需要关注用户可能的疑问点。例如,在依赖管理中提到的`find_package`和`FetchContent`的区别,或者接口库设计的实际应用场景。编译加速策略中的预编译头文件和Unity Build可能对新手来说不太熟悉,需要进一步解释其优缺点。 另外,用户可能希望了解这些策略如何结合起来使用,以及在实际项目中可能会遇到的挑战和解决方案。例如,如何处理符号冲突,或者如何确保编译器的兼容性。这些都属于典型问题解决方案中的内容,需要强调其重要性。 我还需要检查是否有遗漏的关键点。原始回答非常全面,但可能某些高级话题如模块化配置、自定义命令或生成器表达式没有深入探讨。不过,用户的问题主要集中在分析现有文件,所以可能不需要扩展新内容,而是总结现有内容。 最后,我需要确保分析的语言清晰、结构合理,帮助用户快速抓住重点,并理解如何应用这些指南到实际项目中。可能需要使用例子来说明某些概念,或者比较不同方法的适用场景,以增强用户的理解。</think>以下是对CMake大型项目编译指南的深度分析,从结构设计到技术细节的逐层解读: --- ### 一、架构设计分析 1. **模块化构建思想** - 通过`add_subdirectory()`实现分层管理,每个子模块拥有独立CMakeLists.txt - 典型案例: ```cmake project_root/ ├─ src/ │ └─ module1/ # 业务模块 ├─ thirdparty/ # 外部依赖模块 └─ tests/ # 测试专用模块 ``` - 优势:隔离编译依赖,提升并行构建效率 2. **依赖传递控制** - 三种可见性级别: - `PRIVATE`:仅当前目标使用(内部依赖) - `INTERFACE`:仅依赖者使用(头文件/接口库) - `PUBLIC`:联合作用(实现+接口依赖) - 错误示例修正: ```cmake # 错误:未指定作用导致依赖泄漏 target_link_libraries(A B) # 正确:明确声明为私有依赖 target_link_libraries(A PRIVATE B) ``` --- ### 二、关键技术点解析 #### 1. 现代依赖管理对比 | 方法 | 适用场景 | 特点 | |-----------------|-------------------------|-----------------------------------| | `find_package` | 系统预装库 | 依赖系统环境,需处理版本冲突 | | `FetchContent` | 源码级集成 | 自动下载编译,版本控制精确 | | `ExternalProject`| 复杂构建流程 | 支持全生命周期控制,但集成难度高 | #### 2. 编译加速原理 - **预编译头文件(PCH)** ```cmake target_precompile_headers(my_target PUBLIC <vector> <string> "common_headers.h" ) ``` - 效果:减少重复解析头文件时间(提升20%-50%) - 限制:头文件修改会触发全量重编译 - **Unity Build** ```cmake set(CMAKE_UNITY_BUILD_BATCH_SIZE 50) # 控制合并文件数量 ``` - 本质:将多个.cpp合并为编译单元 - 风险:可能引发宏污染或命名冲突 --- ### 三、典型问题深度分析 #### 1. 符号冲突解决方案 ```cmup # 隐藏非公开符号(GCC/Clang) target_compile_options(my_lib PRIVATE -fvisibility=hidden) # 显式导出符号 __attribute__((visibility("default"))) void export_func(); ``` #### 2. 平台构建陷阱 ```cmake # 错误:硬编码路径分隔符 include_directories("src\module1") # 正确:使用CMake路径变量 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") ``` #### 3. 安装机制详解 ```cmake install(EXPORT MyProjectTargets FILE MyProjectTargets.cmake DESTINATION lib/cmake/MyProject) ``` - 生成XXXConfig.cmake文件实现find_package自发现 - 支持版本兼容性检查: ```cmake include(CMakePackageConfigHelpers) write_basic_package_version_file( MyProjectConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion ) ``` --- ### 四、高级实践建议 1. **组件化构建** ```cmake add_library(component STATIC EXCLUDE_FROM_ALL) set_property(TARGET component PROPERTY ARCHIVE_OUTPUT_NAME comp) ``` 2. **动态特性控制** ```cmake option(ENABLE_FEATURE_X "Enable advanced feature" OFF) if(ENABLE_FEATURE_X) target_compile_definitions(my_target PRIVATE USE_FEATURE_X=1) endif() ``` 3. **构建时代码生成** ```cmake add_custom_command( OUTPUT generated_code.cpp COMMAND codegen_tool -o ${CMAKE_CURRENT_BINARY_DIR}/generated_code.cpp DEPENDS schema.xml ) target_sources(my_target PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated_code.cpp) ``` --- ### 五、性能优化指标参考 | 优化手段 | 代码规模阈值 | 预期收益 | 副作用风险 | |------------------|-------------|----------|------------| | 基础并行编译 | >10万行 | 30%-50% | 低 | | PCH预编译头 | >50万行 | 20%-40% | 中 | | Unity Build | >100万行 | 50%-70% | 高 | | 分布式编译 | >500万行 | 80%-90% | 配置复杂 | --- 通过以上分析可见,该CMake指南覆盖了大型项目构建的核心需求。实际应用中需注意: 1. 保持CMakeLists.txt的DRY原则(Don't Repeat Yourself) 2. 使用`CMAKE_BUILD_TYPE`严格区分Debug/Release构建 3. 定期运行`cmake --graphviz=graph.dot`生成依赖图谱进行架构审计
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值