# Course1~3(Oka,Form)
###### tags: `web` `deno` `ccc` `oka` `form`
Course 1
https://www.facebook.com/ccckmit/videos/817332406069771/?idorvanity=266037214366597
---
Course 2
https://www.facebook.com/ccckmit/videos/3328236040831796?idorvanity=266037214366597
[TOC]
# Basic
## Callback
```typescript
function calledHello(f){
f()
}
function hello(){
console.log("Hello")
}
calledHello(hello)
```
Differential
```typescript
function df(f,x,h=0.001){
return (f(x+h)-f(x))/h
}
console.log(df(Math.sin, Math.PI/4))
```
-->f(g(x)) concept
Map
The **`map()`** method **creates a new array** populated with the results of calling a provided function on every element in the calling array.
```typescript
function Mymap(array, f){
let list =[]
for(let i=0;i<array.length;i++){
let element:number = array[i]
var squareElements:number = f(element)
list.push(squareElements)
}
return list
}
function square(x:number=0){
return x*x
}
console.log(Mymap([1,3,5],square))
```
## Object
```typescript
class Studnet{
private name:string =""
setName(name:string){
this.name = name
}
}
let object = new Studnet()
object.setName("meowhecker")
console.log(object)
```
## Parameter
Using object way is going to pass the reference to modify it
```typescript
interface user{
name:string
password:number
}
let user={
name:"meowhecker",
password:123345
}
function Mo(object){
object.name="meow"
}
Mo(user)
console.log(user)
```

# HTTP
## Data exchange (front end <--> back end)
Convert javascript object into JSON form
```typescript
console.log("OBJECT->JSON")
JSON.stringify()
```
Recover it
```typescript
console.log("JSON->OBJECT")
JSON.parse()
```
```typescript
interface user{
name:string
password:number
}
let user={
name:"meowhecker",
password:123345
}
let transIntoJSON = JSON.stringify(user)
console.log(user)
console.log("OBJECT->JSON")
console.log(transIntoJSON)
console.log("<------------------------------------------>")
let JOSNtoObject = JSON.parse(transIntoJSON)
console.log("JSON->OBJECT")
console.log(JOSNtoObject)
```

# [oak](https://deno.land/x/oak@v11.1.0)
## BASIC Server
a middleware framework for Deno native HTTP server
Two of the methods are generally to use
- use()
- listen()
Middleware is added via the `.use()` method and the `.listen()` method will start the server and start processing requests with the registered middleware.
```typescript
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
app.use((context:any)=>{
context.response.body="meowhecker"
})
// function Hello(context){
// context.response.body="meowhecker"
// }
// app.use(Hello)
console.log('start at:http://127.0.0.1:8000')
await app.listen({ port: 8000 });
//commend
// deno run --allow-net oakServer.ts
```
## Args
Pass commend line parameters into the code
Example
```typescript
let port:number=parseInt(Deno.args[0])
```
```typescript
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
app.use((context)=>{
context.response.body="meowhecker"
})
let port:number=parseInt(Deno.args[0])
console.log('start at:http://127.0.0.1:'+port)
await app.listen({ port: port });
//commend
// deno run --allow-net oakServer.ts 6669
```

## HTTP request content
### Get URL
```
pathname=${ctx.request.url.pathname}
```
### Get ALL search parameters
```typescript
searchParams=${ctx.request.url.searchParams}
```
### Get the specific search parameter
```typescript
searchParams.get('name')=${ctx.request.url.searchParams.get('name')}
```
```typescript
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
app.use((ctx:any)=>{
console.log('ctx=', ctx)
console.log('ctx.request=', ctx.request)
console.log('url=', ctx.request.url)
ctx.response.body = `
method=${ctx.request.method}
url=${ctx.request.url.href}
protocol=${ctx.request.url.protocol}
hostname=${ctx.request.url.hostname}
pathname=${ctx.request.url.pathname}
hash=${ctx.request.url.hash}
search=${ctx.request.url.search}
searchParams=${ctx.request.url.searchParams}
searchParams.get('name')=${ctx.request.url.searchParams.get('name')}
headers=${JSON.stringify(Object.fromEntries(ctx.request.headers))}
`;
})
console.log('start at:http://127.0.0.1:8000')
await app.listen({ port: 8000 });
```

### Get request URL / layout
Get URL
```typescript
let pathname = context.request.url.pathname;
```
layout
```typescript
function layout(body){
return `
<html>
<title>Meow</title>
<body>
${body}
</body>
</html>
`
}
```
```typescript
import { Application } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
function layout(body){
return `
<html>
<title>Meow</title>
<body>
${body}
</body>
</html>
`
}
app.use((context:any)=>{
let pathname = context.request.url.pathname;
console.log(pathname)
if(pathname.startsWith("/login")){
context.response.body= layout('<h1>meow</h1>');
}
else{
context.response.body= layout('<h1>fail</h1>');
}
})
console.log('start at:http://127.0.0.1:8000')
await app.listen({ port: 8000 });
```
## Router (return JSON data to front end)
The `Router` class produces middleware which can be used with an `Application` to enable routing based on the pathname of the request.
**javascript object -> JSON Array**
```typescript
context.response.body=Array.from(users.values()) //Convert it into the json form (array.form)
```
```typescript
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
const port:number = 8005
const users = new Map<string,any>()
users.set("1",{
id:"1",
name:"meowhecker",
password:"test123"
})
users.set("2",{
id:"2",
name:"meowmeow",
password:"123"
})
const router = new Router
router.get("/", (context)=>{
context.response.body="meow"
})
.get("/users",(context)=>{
context.response.body=Array.from(users.values()) //Convert it into the json form (array.form)
})
.get("/users/:id", (context) => {
if (users.has(context?.params?.id)) {
context.response.body = users.get(context.params.id)
}
})
const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());
console.log('start at:http://127.0.0.1:'+port)
await app.listen({port:port})
```
## Methods
### Context
- .send()
- The function `send()` is designed to serve static content as part of a middleware function
Example
```typescript
import { Application } from "https://deno.land/x/oak/mod.ts";
const port:number = 8001
const app = new Application();
app.use(async(context,next)=>{
try{
await context.send({
root: `${Deno.cwd()}/public`,
index: "index.html"
})
}
catch{
await next()
}
})
console.log('start at:http://127.0.0.1:'+port)
await app.listen({port:port})
```
### Request
- .url
- An instance of [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) which is based on the full URL for the request. This is in place of having parts of the URL exposed on the rest of the request object.
```javascript
console.log('url=', ctx.request.url)
```
### Response
- .body
- .headers
- .status
- .type
Redirect
```javascript
ctx.response.redirect('https://tw.youtube.com')
```
# Application1(form)
## Declare and Import
```typescript
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
import * as view from "./View.ts"
const port:number = 8200
```
## User Data
```typescript
//User data
interface userAssociatArray{
id:any,
name:string,
password:string
}
const userAssociatArray =[
{id:"1",name:"meowhecker",password:"test123"},
{id:"2", name:"meowmeow", password:"123"}
]
```
## Router
```typescript
const router:any = new Router
router.get("/",listings)
.get("/create",create)
.get("/listing/:id",show)
.post("/store",store)
```
## app
```typescript
const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());
```
Controller
```typescript
//Controller Meow
async function listings(ctx:any){
ctx.response.body = await view.listings(userAssociatArray)
}
async function show(ctx:any){
//fetch URL parameter
const URLid = ctx.params.id
const singleUserData = userAssociatArray[URLid]
if(!singleUserData){
ctx.throw(404,"invalid ID")
}else{
ctx.response.body = await view.listingPage(singleUserData)
}
}
async function create(ctx:any){
ctx.response.body = await view.CreatePage()
}
async function store(ctx:any){
// console.log(body)
// console.log(body.value)
// console.log(body.type)
const body = ctx.request.body()
const parse = await body.value
const newUserObject:any={}
for( const [key,value] of parse ) {
newUserObject[key] = value
}
console.log("FormValue =",newUserObject)
const id = userAssociatArray.push(newUserObject)
newUserObject.create_at = new Date() //create_at is a Database column
newUserObject.id =id
ctx.response.redirect("/")
}
```
```typescript
console.log('start at:http://127.0.0.1:'+port)
await app.listen({port:port})
```
> .push
Definition and Usage
The push() method adds new items to the end of an array.
The push() method changes the length of the array.
he push() method returns the new length.
## View
```typescript
let layout = (title:string,content:any)=>{
return ` <html>
<head>
<title>${title}</title>
<style>
body {
padding: 80px;
font: 16px Helvetica, Arial;
}
h1 {
font-size: 2em;
}
h2 {
font-size: 1.2em;
}
#posts {
margin: 0;
padding: 0;
}
#posts li {
margin: 40px 0;
padding: 0;
padding-bottom: 20px;
border-bottom: 1px solid #eee;
list-style: none;
}
#posts li:last-child {
border-bottom: none;
}
textarea {
width: 500px;
height: 300px;
}
input[type=text],
textarea {
border: 1px solid #eee;
border-top-color: #ddd;
border-left-color: #ddd;
border-radius: 2px;
padding: 15px;
font-size: .8em;
}
input[type=text] {
width: 500px;
}
</style>
</head>
<body>
<section id="content">
${content}
</section>
</body>
</html>`
}
function listings(userAssociatArray){
let list:any = []
//Using loop to fetch eache element in javascript object
for(let user of userAssociatArray){
list.push(`
<li>
<h2>USER: ${user.name}</h2>
<p><a href="/listing/${user.id}">User Information</a></p>
</li>
`)
}
//Embedding user information
const content =
`<h1>Posts</h1>
<p>You have <strong>${userAssociatArray.length}</strong> posts!</p>
<p><a href="/create">Create a Post</a></p>
<ul id="posts">
${list.join('\n')}
</ul>
`
return layout("post",content)
}
//Show single listing
function listingPage(singleUserData){
return layout("single listing",`
<h1>User: ${singleUserData.name}</h1>
<pre>Password: ${singleUserData.password}</pre>
`)
}
//Create Page
function CreatePage(){
return layout("New",`<h1>New Post</h1>
<p>Create a new post.</p>
<form action="/store" method="post">
<p><input type="text" placeholder="name" name="name"></p>
<p><input type="text" placeholder="password" name="password"></p>
<!--<p><textarea placeholder="Contents" name="body"></textarea></p>-->
<p><input type="submit" value="Create"></p>
</form>`)
}
export{layout, CreatePage, listings, listingPage}
```
>list.join()
Definition and Usage
The join() method returns an array as a string.
The join() method does not change the original array.
Any separator can be specified. The default is comma (,).
----
## Error solves

solve way
```typescript
const newUserObject:any={}
```
[Reference Document](https://stackoverflow.com/questions/12710905/how-do-i-dynamically-assign-properties-to-an-object-in-typescript)
## Result

自己的網站自己打XD

## Defense (Stored-XSS)
- .replace()
- adding double quote
(But too many ways could break it and execute js If I want )
# HTTP status
1xx informational response
2xx success
3xx redirection
4xx client errors
5xx server errors
---
https://blog.csdn.net/xiaoanzi123/article/details/107028766