ㅡ. 도입

google bigQuery 데이터를 node.js에서 fetch해서 vue.js 로 데이터를 뿌려주는 워크플로우

 

ㅡ. 문제

CORS 문제

node.js에서 express 를 사용하고 있었기 때문에 아래와 같이 cors 패키지를 설치했음에도 

$ npm install --save cors
const cors = require('cors'); //app.js
app.use(cors()); //app.js

Same-origin policy 라는 에러를 뿜어냈습니다. 호스트는 ip + port 를 의미하는데, port 가 달라지면서 (vue.js:8090, node.js:3000) 동일 호스트에서 호출받는 정책이 깨지면서 에러가 발생하였습니다. 즉, 호스트와 오리진이 서로 다른것입니다. 여기서 의미하는 호스트는 요청을 처리하는 서버, api서버를 의미하고 오리진은 요청을 보낸곳의 호스트를 의미합니다. vue.js가 될것입니다. 

(+ same policy 정책은 브라우저에서 임의로 정해준다고 합니다. 브라우저에서 요청시에 헤더를 보관하여 처리하는데 오리진에 요청 보낸곳의 URL를 헤더에 추가한다던지 작업을 수행한다고 합니다. ) 

 

ㅡ. vue.js

import Axios from "axios";
// import store from "../vuex/store.js";
const URL = "http://localhost:3000"
const requestCategoryBasic = (data, callback, errorCallback) =>{
Axios.post(URL + '/bigquery/?category='+data[0])
.then(response=>{
callback(response);
console.log(response)
}).catch(exp=>{
console.log(exp)
errorCallback(exp);
})
}
const proxyApi = {
requestCategoryBasic: (data, callback, errorCallback) =>requestCategoryBasic(data, callback, errorCallback),
}
export default proxyApi;

ㅡ. node.js

var express = require('express');
var router = express.Router();
const {BigQuery} = require('@google-cloud/bigquery');
const query=async(res, category)=>{
// Queries the U.S. given names dataset for the state of Texas.
const bigquery = new BigQuery();
const query = "SELECT * FROM `fluid-crane-284202.prototyping_dataset.category_basic` WHERE category="+"'"+category+"'";
console.log(query)
console.log(category)
//const query = "SELECT name FROM \`bigquery-public-data.usa_names.usa_1910_2013\` WHERE state = 'TX' LIMIT 100";
// For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
const options = {
query: query,
// Location must match that of the dataset(s) referenced in the query.
location: 'US',
};
// Run the query as a job
const [job] = await bigquery.createQueryJob(options);
console.log(`Job ${job.id} started.`);
// Wait for the query to finish
const [rows] = await job.getQueryResults();
// Print the results
console.log('Rows:');
rows.forEach(row => console.log(row));
res.send([rows])
}
/* POST users listing. */
router.post('/', async function(req, res, next) {
//res.json(users);
await query(res, req.query.category)
});
module.exports = router;

 

ㅡ. 해결 방법

node.js 란에 아래 코드를 추가하게 되면

res.set({'access-control-allow-origin':'*'});

* 는 ip 를 대신해도 괜찮습니다. * 의미는 전체 호스트의 ip, port 를 허용하겠다 라는 의미입니다. 

ㅡ. ref

https://kamang-it.tistory.com/entry/Web%EB%8F%99%EC%9D%BC-%EC%B6%9C%EC%B2%98-%EC%A0%95%EC%B1%85-CORS-%EB%8F%84%EB%8C%80%EC%B2%B4-%EB%AD%98%EA%B9%8C