Nodejs + 自定义 CORS

nodejs + 自定义 cors

cors(跨源资源共享) 是一种允许一个域上的 web 应用程序访问另一个域上的资源的机制。当开发前端和后端分离并通过 api 进行通信的应用程序时,这一点至关重要。

这里有一篇文章解释了在 node.js 和 express 中不使用外部库的 cors 实现:

"use strict";/*jshint node:true */var simplemethods, simplerequestheaders, simpleresponseheaders, tolowercase, checkoriginmatch, origin;object.defineproperty(exports, "simplemethods", {    get: function () {        return [            "get",            "head",            "post",            "put",            "delete"        ];    }});simplemethods = exports.simplemethods;object.defineproperty(exports, "origin", {    get: function () {        return ["http://localhost:3000"];    }});origin = exports.origin;

export simplemethods:定义 cors 请求允许的 http 方法(例如 get、post、put 等)。

导出来源:指定允许访问的来源列表。在此示例中,允许使用 http://localhost:3000。

object.defineproperty(exports, "simplerequestheaders", {    get: function () {        return ["accept", "accept-language", "content-language", "content-type", "authorization", "token"];    }});simplerequestheaders = exports.simplerequestheaders;object.defineproperty(exports, "simpleresponseheaders", {    get: function () {        return ["cache-control", "content-language", "content-type", "expires", "last-modified", "pragma"];    }});simpleresponseheaders = exports.simpleresponseheaders;

导出 simplerequestheaders:定义跨域请求中客户端允许的请求标头。

导出 simpleresponseheaders:定义从服务器到客户端允许的响应标头。

checkoriginmatch = function (originheader, origins, callback) {    if (typeof origins === "function") {        origins(originheader, function (err, allow) {            callback(err, allow);        });    } else if (origins.length > 0) {        callback(null, origins.some(function (origin) {            return origin === originheader;        }));    } else {        callback(null, true);    }};

函数 checkoriginmatch:检查请求来源是否与允许的来源列表匹配。如果匹配,则允许请求。

exports.create = function (options) {    options = options || {};    options.origins = options.origins || origin;    options.methods = options.methods || simplemethods;

来源和方法选项的初始化,如果未提供,则使用来自 origin 和 simplemethods 的默认值。

设置请求和响应标头

 if (options.hasownproperty("requestheaders") === true) {        options.requestheaders = tolowercase(options.requestheaders);    } else {        options.requestheaders = simplerequestheaders;    }    if (options.hasownproperty("responseheaders") === true) {        options.responseheaders = tolowercase(options.responseheaders);    } else {        options.responseheaders = simpleresponseheaders;    }

设置允许的请求(requestheaders)和响应(responseheaders)标头。将任何给定的请求或响应标头转换为小写。

附加中间件配置

 options.maxage = options.maxage || null;    options.supportscredentials = options.supportscredentials || false;    if (options.hasownproperty("endpreflightrequests") === false) {        options.endpreflightrequests = true;    }

maxage:指定 cors 预检的最大缓存期限。 supportcredentials:确定服务器是否支持跨域请求中的凭据(cookie 或令牌)。 endpreflightrequests:决定服务器是否应终止预检请求(选项)或继续执行下一个中间件。

 return function (req, res, next) {        if (!req.headers.hasownproperty("origin")) {            next();        } else {            checkoriginmatch(req.headers.origin, options.origins, function (err, originmatches) {                if (err !== null) {                    next(err);                } else {                    var endpreflight = function () {                        if (options.endpreflightrequests === true) {                            res.writehead(204);                            res.end();                        } else {                            next();                        }                    };

函数 endpreflight:如果 endpreflightrequests 设置为 true,则结束预检(options)请求。来源检查:使用 checkoriginmatch 来验证请求来源是否与允许的来源匹配。

处理预检请求(选项)

 if (req.method === "options") {                        if (!req.headers.hasownproperty("access-control-request-method")) {                            endpreflight();                        } else {                            requestmethod = req.headers["access-control-request-method"];                            if (req.headers.hasownproperty("access-control-request-headers")) {                                requestheaders = tolowercase(req.headers["access-control-request-headers"].split(/,s*/));                            } else {                                requestheaders = [];                            }                            methodmatches = options.methods.indexof(requestmethod) !== -1;                            if (!methodmatches) {                                endpreflight();                            } else {                                headersmatch = requestheaders.every(function (requestheader) {                                    return options.requestheaders.includes(requestheader);                                });                                if (!headersmatch) {                                    endpreflight();                                } else {                                    if (options.supportscredentials) {                                        res.setheader("access-control-allow-origin", req.headers.origin);                                        res.setheader("access-control-allow-credentials", "true");                                    } else {                                        res.setheader("access-control-allow-origin", "*");                                    }                                    if (options.maxage !== null) {                                        res.setheader("access-control-max-age", options.maxage);                                    }                                    res.setheader("access-control-allow-methods", options.methods.join(","));                                    res.setheader("access-control-allow-headers", options.requestheaders.join(","));                                    endpreflight();                                }                            }                        }                    }

请求方法和标头匹配:检查请求方法和标头是否与允许的匹配。 cors 响应标头:设置 cors 标头,例如 access-control-allow-origin、access-control-allow-credentials、access-control-allow-methods 等

在响应中公开标头
} 其他 {
if (options.supportscredentials) {
res.setheader(“access-control-allow-origin”, req.headers.origin);
res.setheader(“access-control-allow-credentials”, “true”);
} 其他 {
res.setheader(“access-control-allow-origin”, “*”);
}

                    exposedheaders = options.responseheaders.filter(function (header) {                        return !simpleresponseheaders.includes(header);                    });                    if (exposedheaders.length > 0) {                        res.setheader("access-control-expose-headers", exposedheaders.join(","));                    }                    next();                }            }        });    }};
 } else {                        if (options.supportsCredentials) {                            res.setHeader("Access-Control-Allow-Origin", req.headers.origin);                            res.setHeader("Access-Control-Allow-Credentials", "true");                        } else {                            res.setHeader("Access-Control-Allow-Origin", "*");                        }                        exposedHeaders = options.responseHeaders.filter(function (header) {                            return !simpleResponseHeaders.includes(header);                        });                        if (exposedHeaders.length > 0) {                            res.setHeader("Access-Control-Expose-Headers", exposedHeaders.join(","));                        }                        next();                    }                }            });        }    };

access-control-expose-headers:如果 simpleresponseheaders 中未包含自定义标头,则设置客户端可访问的响应标头。

这就是如何在 node.js 中实现自定义 cors,而无需使用任何库。完整的脚本可以参考这个例子

以上就是Nodejs + 自定义 CORS的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1497477.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 19:33:28
下一篇 2025年12月19日 19:33:44

相关推荐

发表回复

登录后才能评论
关注微信