Skip to content

Commit

Permalink
Document 增加 httpOnly 属性,用于操作 cookie
Browse files Browse the repository at this point in the history
  • Loading branch information
yong.teng committed Jan 18, 2023
1 parent 94d2230 commit c6e7250
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# 更新日志

## [v2.1.0](https://github.com/buession/buession-prototype/releases/tag/2.1.0)(2023-01-18)

### ⭐ 新特性

- Document 增加 httpOnly 属性,用于操作 cookie


## [v2.0.2](https://github.com/buession/buession-prototype/releases/tag/2.0.2)(2022-10-01)

### 🐞 BUG 修复
Expand Down
16 changes: 16 additions & 0 deletions example/cookie.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>buession prototype</title>
</head>
<body>
<script src="../dist/prototype.umd.js"></script>
<script type="text/javascript">
document.httpCookie.set("a", "中国");
alert(document.httpCookie.get("a"))
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@buession/prototype",
"alias": "prototype",
"version": "v2.0.2",
"version": "v2.1.0",
"description": "A native object extension framework for Javascript.",
"homepage": "https://buession.github.io/buession-prototype/",
"author": {
Expand Down
151 changes: 151 additions & 0 deletions src/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ interface Document {
*/
readonly msFullscreenElement: Element | null;

/**
* 获取 Cookie 对象
*
* @return Cookie 对象
*/
readonly httpCookie: Cookie;

/**
* 请求进入全屏模式
*
Expand Down Expand Up @@ -167,6 +174,139 @@ interface HTMLElement {
msRequestFullscreen(): Promise<void>;
}

enum SameSite {
NONE = 'None',

LAX = 'Lax',

STRICT = 'Strict'
}

interface CookieOptions {
/**
* Cookie 作用域
*/
domain?: String;

/**
* Cookie 作用路径
*/
path?: String;

/**
* Cookie 过期时间
*/
expires?: Number | Date;

/**
* 是否启用安全 Cookie
*/
secure?: Boolean;

/**
* 是否为 HttpOnly
*/
httpOnly?: Boolean;

/**
* SameSite
*/
sameSite?: SameSite;
}

interface Cookie {
/**
* 设置 Cookie 值
*
* @param name Cookie 名称
* @param value Cookie 值
* @param options Cookie 选项
* @return Cookie 值
*/
set(name: string, value: string | null | undefined, options?: CookieOptions): string;

/**
* 获取 Cookie 值
*
* @param name Cookie 名称
* @return Cookie 值;不存在时,返回 null
*/
get(name: string): string | null;

/**
* 删除 Cookie
*
* @param name Cookie 名称
* @param options Cookie 选项
*/
delete(name: string, options?: CookieOptions): void;
}

class CookieInstance implements Cookie {
public constructor () {
}

public set(name: string, value: string | null | undefined, options?: CookieOptions): string {
const $name = name = encodeURIComponent(name)
.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent);
const $value = value ? encodeURIComponent(value)
.replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent) : '';

let stringifiedAttributes = '';

if (options) {
stringifiedAttributes += options.domain ? '; domain=' + options.domain : '';
stringifiedAttributes += options.path ? '; path=' + options.path : '';

if (options.expires) {
const $expiresDate = options.expires instanceof Date ? options.expires : new Date(Date.now() + (options.expires as number) * 864e5);

stringifiedAttributes += options.expires ? '; expires=' + $expiresDate.toUTCString() : '';
}

stringifiedAttributes += options.sameSite ? '; sameSite=' + options.sameSite : '';

if (Object.isBoolean(options.secure) && options.secure) {
stringifiedAttributes += options.expires ? '; secure' : '';
}

if (Object.isBoolean(options.httpOnly) && options.httpOnly) {
stringifiedAttributes += options.httpOnly ? '; httpOnly' : '';
}
}

return document.cookie = $name + '=' + $value + stringifiedAttributes;
}

public get(name: string): string | null {
const cookies = document.cookie ? document.cookie.split('; ') : [];

for (let i = 0; i < cookies.length; i++) {
const parts = cookies[i].split('=');
const $name = decodeURIComponent(parts[0]);
let $value = parts.slice(1).join('=');

if ($name === name) {
if ($value[0] === '"') {
$value = $value.slice(1, -1)
}

return $value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
}
}

return null;
}

public delete(name: string, options?: CookieOptions): void {
const $options = options ? options : {};

$options.expires = -1;

this.set(name, '', $options);
}
}

declare var Document: {
prototype: Document;

Expand Down Expand Up @@ -232,6 +372,17 @@ Object.defineProperty(document, "fullScreenElement", {
writable: false
});

/**
* 返回 Cookie 对象
*
* @return Cookie 对象
*/
Object.defineProperty(document, "httpCookie", {
value: new CookieInstance(),
configurable: true,
writable: false
});

/**
* 请求进入全屏模式
*
Expand Down

0 comments on commit c6e7250

Please sign in to comment.