82°

跨域访问CORS

上次研究了一下利用Heroku app写了一个webservice,供Salesforce Lightning fetch通过apex调用,后来由于只是读取数据,所以提出要改成直接在js里调用webserivce, 不通过Apex, 这里就涉及到一个跨域访问的问题。

 

对大佬而言这么简单的问题我研究了3天,简直蜗牛了,不过还好最终捣鼓通了。

起初试了很多方法遇到了一个Preflight Request,翻译过来叫什么预起飞请求, 说的是相对于普通的请求,“预起飞”请求需要在实际请求(比如POST)的同时,浏览器会先向服务器发送一个OPTION请求用来验证请求数据对访问数据是否安全,确认安全后实际的请求才会被发出并处理。因此我遇到一个错误,服务器端log显示, OPTION 请求返回200, ok, 但是实际POST请求却总是报错 “unexpected token o in json at position express” ,  这种情况下,一种解决方法说可以安装 cors 包来解决(cors 包会自动处理OPTIONS请求), 但是我试了很多次都不好使,放弃了; 还有种方式就是改变Content-Type 类型由 “Application/json” 变成 “text/plain”, 使得请求转变成普通类型,避免预起飞(Preflight),这种方式成功了。

https://dev.to/effingkay/cors-preflighted-requests--options-method-3024

 

 

然而之后又产生了一个新的错误说"Refused to connect to because it violates the following Content Security Policy directive: "connect-src 'self' example1.com example2.com", 查其原因是因为Content Security Policy 中connectSrc directive配置了允许访问的源,这里我用了 helmet-csp package。

https://helmetjs.github.io/docs/csp/

var csp = require('helmet-csp');
app.use(csp({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-inline'"],
    reportUri: '/report-violation',
    connectSrc:[ "'self'"],
    objectSrc: ["'none'"],
    upgradeInsecureRequests: true,
    workerSrc: false  
  },
  reportOnly: true
}));

 

 

然而之后又产生了一个新的错误说是“Access to fetch at  from origin has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.” 查明原因是因为,浏览器并不知道其访问的内容是否安全,CORS策略中有个Header Access-Control-Allow-Origin, 服务器端需要在响应中添加此Header以告知浏览器该返回响应中的数据对于浏览器当前域是允许的,否则浏览器会阻止访问。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

 

最终调通了。

本文转载自博客园,原文链接:https://www.cnblogs.com/faithfatebe/p/12221092.html

全部评论: 0

    我有话说: