当我在'no-cors'模式下获取资源时,为什么body-parser会失败?

时间:2017-11-22 14:11:55

标签: javascript cross-domain fetch body-parser

我从文件系统打开一个静态页面,该页面试图从在localhost上运行的服务器(即/的目录列表)中获取资源。浏览器拒绝转发此请求并建议:

If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

然后我使用'no-cors'提交请求:

let body=JSON.stringify({action:"listfiles",path:"/"})

let headers = new Headers()
headers.append("Content-Type", "application/json");               

fetch('http://localhost:9000/ajax',{
    method: 'POST',
    headers: headers,
    body: body,
    mode: 'no-cors'
}).then(
    response=>response.json()
).then(
    data=>this.onload(data)
)

在服务器端,我使用express以下列方式:

app.use('/ajax',bodyParser.json())

app.post("/ajax",function(req,res){    
  let action=req.body.action  
  console.log(`ajax ${action}`)
}

这次浏览器允许请求通过,甚至app.post获取请求,只是请求正文未正确解析,而不是'listfiles' undefined actionfrom selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--disable-notifications") browser = webdriver.Chrome('C:\Python34\Lib\site-packages\selenium\webdriver\chromedriver.exe', chrome_options=options) 1}}。 (如果我从localhost加载页面,则不会出现同样的问题。)

2 个答案:

答案 0 :(得分:1)

因为您正在尝试进行跨域调用(协议file:与协议http:不同)。同源协议由浏览器强制执行,因此您的服务器看到请求并不奇怪。该请求不包含允许浏览器为您的代码提供响应的CORS标头,因此它不会;你无论如何都禁用了CORS。

答案 1 :(得分:0)

来自https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

  

"跨源资源共享标准的工作原理是添加新的HTTP标头,允许服务器描述允许使用Web浏览器读取该信息的起源集。此外,对于可能对服务器数据造成副作用的HTTP请求方法(特别是对于GET以外的HTTP方法,或对某些MIME类型的POST使用),规范要求浏览器"预检& #34;请求,使用HTTP OPTIONS请求方法从服务器请求支持的方法,然后,在"批准"从服务器,使用实际的HTTP请求方法发送实际请求。 "

我的请求的问题在于它不符合简单条件。这是因为它包含Content-Type: application/json标头,以便正文解析器中间件将文档主体解析为json。因此它会触发预检请求。

  

"简单的要求

     

某些请求不会触发CORS预检。这些在本文中称为“简单请求”,尽管Fetch规范(定义CORS)不使用该术语。不触发CORS预检的请求 - 所谓的“简单请求” - 满足以下所有条件:..."

此处列出的条件包括方法限制,您可以设置的标题等。有关详细信息,请查看文档。

虽然我在简单请求中允许使用(POST)方法,并且对于简单请求也允许设置Content-Type标头,但Content-Type的唯一可能值是

application/x-www-form-urlencoded
multipart/form-data
text/plain

要求获得简单的资格。

由于我的服务器不知道预检请求,因此无法正常处理我的请求。

另请参阅答案评论,了解客户端和服务器端需要传递哪些附加标头,以使请求按预期工作。